1 /*
2  *  Catch v1.3.1
3  *  Generated: 2015-12-09 18:10:29.846134
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()
6252         :   m_currentSortOrder( RunTests::InDeclarationOrder ),
6253             m_unnamedCount( 0 )
6254         {}
6255         virtual ~TestRegistry();
6256 
registerTest(TestCase const & testCase)6257         virtual void registerTest( TestCase const& testCase ) {
6258             std::string name = testCase.getTestCaseInfo().name;
6259             if( name == "" ) {
6260                 std::ostringstream oss;
6261                 oss << "Anonymous test case " << ++m_unnamedCount;
6262                 return registerTest( testCase.withName( oss.str() ) );
6263             }
6264             m_functions.push_back( testCase );
6265         }
6266 
getAllTests() const6267         virtual std::vector<TestCase> const& getAllTests() const {
6268             return m_functions;
6269         }
getAllTestsSorted(IConfig const & config) const6270         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
6271             if( m_sortedFunctions.empty() )
6272                 enforceNoDuplicateTestCases( m_functions );
6273 
6274             if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
6275                 m_sortedFunctions = sortTests( config, m_functions );
6276                 m_currentSortOrder = config.runOrder();
6277             }
6278             return m_sortedFunctions;
6279         }
6280 
6281     private:
6282         std::vector<TestCase> m_functions;
6283         mutable RunTests::InWhatOrder m_currentSortOrder;
6284         mutable std::vector<TestCase> m_sortedFunctions;
6285         size_t m_unnamedCount;
6286         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
6287     };
6288 
6289     ///////////////////////////////////////////////////////////////////////////
6290 
6291     class FreeFunctionTestCase : public SharedImpl<ITestCase> {
6292     public:
6293 
FreeFunctionTestCase(TestFunction fun)6294         FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
6295 
invoke() const6296         virtual void invoke() const {
6297             m_fun();
6298         }
6299 
6300     private:
6301         virtual ~FreeFunctionTestCase();
6302 
6303         TestFunction m_fun;
6304     };
6305 
extractClassName(std::string const & classOrQualifiedMethodName)6306     inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
6307         std::string className = classOrQualifiedMethodName;
6308         if( startsWith( className, "&" ) )
6309         {
6310             std::size_t lastColons = className.rfind( "::" );
6311             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
6312             if( penultimateColons == std::string::npos )
6313                 penultimateColons = 1;
6314             className = className.substr( penultimateColons, lastColons-penultimateColons );
6315         }
6316         return className;
6317     }
6318 
registerTestCase(ITestCase * testCase,char const * classOrQualifiedMethodName,NameAndDesc const & nameAndDesc,SourceLineInfo const & lineInfo)6319     void registerTestCase
6320         (   ITestCase* testCase,
6321             char const* classOrQualifiedMethodName,
6322             NameAndDesc const& nameAndDesc,
6323             SourceLineInfo const& lineInfo ) {
6324 
6325         getMutableRegistryHub().registerTest
6326             ( makeTestCase
6327                 (   testCase,
6328                     extractClassName( classOrQualifiedMethodName ),
6329                     nameAndDesc.name,
6330                     nameAndDesc.description,
6331                     lineInfo ) );
6332     }
registerTestCaseFunction(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)6333     void registerTestCaseFunction
6334         (   TestFunction function,
6335             SourceLineInfo const& lineInfo,
6336             NameAndDesc const& nameAndDesc ) {
6337         registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
6338     }
6339 
6340     ///////////////////////////////////////////////////////////////////////////
6341 
AutoReg(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)6342     AutoReg::AutoReg
6343         (   TestFunction function,
6344             SourceLineInfo const& lineInfo,
6345             NameAndDesc const& nameAndDesc ) {
6346         registerTestCaseFunction( function, lineInfo, nameAndDesc );
6347     }
6348 
~AutoReg()6349     AutoReg::~AutoReg() {}
6350 
6351 } // end namespace Catch
6352 
6353 // #included from: catch_reporter_registry.hpp
6354 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
6355 
6356 #include <map>
6357 
6358 namespace Catch {
6359 
6360     class ReporterRegistry : public IReporterRegistry {
6361 
6362     public:
6363 
~ReporterRegistry()6364         virtual ~ReporterRegistry() CATCH_OVERRIDE {}
6365 
create(std::string const & name,Ptr<IConfig const> const & config) const6366         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
6367             FactoryMap::const_iterator it =  m_factories.find( name );
6368             if( it == m_factories.end() )
6369                 return CATCH_NULL;
6370             return it->second->create( ReporterConfig( config ) );
6371         }
6372 
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)6373         void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
6374             m_factories.insert( std::make_pair( name, factory ) );
6375         }
registerListener(Ptr<IReporterFactory> const & factory)6376         void registerListener( Ptr<IReporterFactory> const& factory ) {
6377             m_listeners.push_back( factory );
6378         }
6379 
getFactories() const6380         virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
6381             return m_factories;
6382         }
getListeners() const6383         virtual Listeners const& getListeners() const CATCH_OVERRIDE {
6384             return m_listeners;
6385         }
6386 
6387     private:
6388         FactoryMap m_factories;
6389         Listeners m_listeners;
6390     };
6391 }
6392 
6393 // #included from: catch_exception_translator_registry.hpp
6394 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
6395 
6396 #ifdef __OBJC__
6397 #import "Foundation/Foundation.h"
6398 #endif
6399 
6400 namespace Catch {
6401 
6402     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
6403     public:
~ExceptionTranslatorRegistry()6404         ~ExceptionTranslatorRegistry() {
6405             deleteAll( m_translators );
6406         }
6407 
registerTranslator(const IExceptionTranslator * translator)6408         virtual void registerTranslator( const IExceptionTranslator* translator ) {
6409             m_translators.push_back( translator );
6410         }
6411 
translateActiveException() const6412         virtual std::string translateActiveException() const {
6413             try {
6414 #ifdef __OBJC__
6415                 // In Objective-C try objective-c exceptions first
6416                 @try {
6417                     return tryTranslators();
6418                 }
6419                 @catch (NSException *exception) {
6420                     return Catch::toString( [exception description] );
6421                 }
6422 #else
6423                 return tryTranslators();
6424 #endif
6425             }
6426             catch( TestFailureException& ) {
6427                 throw;
6428             }
6429             catch( std::exception& ex ) {
6430                 return ex.what();
6431             }
6432             catch( std::string& msg ) {
6433                 return msg;
6434             }
6435             catch( const char* msg ) {
6436                 return msg;
6437             }
6438             catch(...) {
6439                 return "Unknown exception";
6440             }
6441         }
6442 
tryTranslators() const6443         std::string tryTranslators() const {
6444             if( m_translators.empty() )
6445                 throw;
6446             else
6447                 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
6448         }
6449 
6450     private:
6451         std::vector<const IExceptionTranslator*> m_translators;
6452     };
6453 }
6454 
6455 namespace Catch {
6456 
6457     namespace {
6458 
6459         class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
6460 
6461             RegistryHub( RegistryHub const& );
6462             void operator=( RegistryHub const& );
6463 
6464         public: // IRegistryHub
RegistryHub()6465             RegistryHub() {
6466             }
getReporterRegistry() const6467             virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
6468                 return m_reporterRegistry;
6469             }
getTestCaseRegistry() const6470             virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
6471                 return m_testCaseRegistry;
6472             }
getExceptionTranslatorRegistry()6473             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
6474                 return m_exceptionTranslatorRegistry;
6475             }
6476 
6477         public: // IMutableRegistryHub
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)6478             virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6479                 m_reporterRegistry.registerReporter( name, factory );
6480             }
registerListener(Ptr<IReporterFactory> const & factory)6481             virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6482                 m_reporterRegistry.registerListener( factory );
6483             }
registerTest(TestCase const & testInfo)6484             virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
6485                 m_testCaseRegistry.registerTest( testInfo );
6486             }
registerTranslator(const IExceptionTranslator * translator)6487             virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
6488                 m_exceptionTranslatorRegistry.registerTranslator( translator );
6489             }
6490 
6491         private:
6492             TestRegistry m_testCaseRegistry;
6493             ReporterRegistry m_reporterRegistry;
6494             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
6495         };
6496 
6497         // Single, global, instance
getTheRegistryHub()6498         inline RegistryHub*& getTheRegistryHub() {
6499             static RegistryHub* theRegistryHub = CATCH_NULL;
6500             if( !theRegistryHub )
6501                 theRegistryHub = new RegistryHub();
6502             return theRegistryHub;
6503         }
6504     }
6505 
getRegistryHub()6506     IRegistryHub& getRegistryHub() {
6507         return *getTheRegistryHub();
6508     }
getMutableRegistryHub()6509     IMutableRegistryHub& getMutableRegistryHub() {
6510         return *getTheRegistryHub();
6511     }
cleanUp()6512     void cleanUp() {
6513         delete getTheRegistryHub();
6514         getTheRegistryHub() = CATCH_NULL;
6515         cleanUpContext();
6516     }
translateActiveException()6517     std::string translateActiveException() {
6518         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
6519     }
6520 
6521 } // end namespace Catch
6522 
6523 // #included from: catch_notimplemented_exception.hpp
6524 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
6525 
6526 #include <ostream>
6527 
6528 namespace Catch {
6529 
NotImplementedException(SourceLineInfo const & lineInfo)6530     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
6531     :   m_lineInfo( lineInfo ) {
6532         std::ostringstream oss;
6533         oss << lineInfo << ": function ";
6534         oss << "not implemented";
6535         m_what = oss.str();
6536     }
6537 
what() const6538     const char* NotImplementedException::what() const CATCH_NOEXCEPT {
6539         return m_what.c_str();
6540     }
6541 
6542 } // end namespace Catch
6543 
6544 // #included from: catch_context_impl.hpp
6545 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
6546 
6547 // #included from: catch_stream.hpp
6548 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
6549 
6550 #include <stdexcept>
6551 #include <cstdio>
6552 #include <iostream>
6553 
6554 namespace Catch {
6555 
6556     template<typename WriterF, size_t bufferSize=256>
6557     class StreamBufImpl : public StreamBufBase {
6558         char data[bufferSize];
6559         WriterF m_writer;
6560 
6561     public:
StreamBufImpl()6562         StreamBufImpl() {
6563             setp( data, data + sizeof(data) );
6564         }
6565 
~StreamBufImpl()6566         ~StreamBufImpl() CATCH_NOEXCEPT {
6567             sync();
6568         }
6569 
6570     private:
overflow(int c)6571         int overflow( int c ) {
6572             sync();
6573 
6574             if( c != EOF ) {
6575                 if( pbase() == epptr() )
6576                     m_writer( std::string( 1, static_cast<char>( c ) ) );
6577                 else
6578                     sputc( static_cast<char>( c ) );
6579             }
6580             return 0;
6581         }
6582 
sync()6583         int sync() {
6584             if( pbase() != pptr() ) {
6585                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6586                 setp( pbase(), epptr() );
6587             }
6588             return 0;
6589         }
6590     };
6591 
6592     ///////////////////////////////////////////////////////////////////////////
6593 
FileStream(std::string const & filename)6594     FileStream::FileStream( std::string const& filename ) {
6595         m_ofs.open( filename.c_str() );
6596         if( m_ofs.fail() ) {
6597             std::ostringstream oss;
6598             oss << "Unable to open file: '" << filename << "'";
6599             throw std::domain_error( oss.str() );
6600         }
6601     }
6602 
stream() const6603     std::ostream& FileStream::stream() const {
6604         return m_ofs;
6605     }
6606 
6607     struct OutputDebugWriter {
6608 
operator ()Catch::OutputDebugWriter6609         void operator()( std::string const&str ) {
6610             writeToDebugConsole( str );
6611         }
6612     };
6613 
DebugOutStream()6614     DebugOutStream::DebugOutStream()
6615     :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
6616         m_os( m_streamBuf.get() )
6617     {}
6618 
stream() const6619     std::ostream& DebugOutStream::stream() const {
6620         return m_os;
6621     }
6622 
6623     // Store the streambuf from cout up-front because
6624     // cout may get redirected when running tests
CoutStream()6625     CoutStream::CoutStream()
6626     :   m_os( Catch::cout().rdbuf() )
6627     {}
6628 
stream() const6629     std::ostream& CoutStream::stream() const {
6630         return m_os;
6631     }
6632 
6633 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
cout()6634     std::ostream& cout() {
6635         return std::cout;
6636     }
cerr()6637     std::ostream& cerr() {
6638         return std::cerr;
6639     }
6640 #endif
6641 }
6642 
6643 namespace Catch {
6644 
6645     class Context : public IMutableContext {
6646 
Context()6647         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
6648         Context( Context const& );
6649         void operator=( Context const& );
6650 
6651     public: // IContext
getResultCapture()6652         virtual IResultCapture* getResultCapture() {
6653             return m_resultCapture;
6654         }
getRunner()6655         virtual IRunner* getRunner() {
6656             return m_runner;
6657         }
getGeneratorIndex(std::string const & fileInfo,size_t totalSize)6658         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
6659             return getGeneratorsForCurrentTest()
6660             .getGeneratorInfo( fileInfo, totalSize )
6661             .getCurrentIndex();
6662         }
advanceGeneratorsForCurrentTest()6663         virtual bool advanceGeneratorsForCurrentTest() {
6664             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6665             return generators && generators->moveNext();
6666         }
6667 
getConfig() const6668         virtual Ptr<IConfig const> getConfig() const {
6669             return m_config;
6670         }
6671 
6672     public: // IMutableContext
setResultCapture(IResultCapture * resultCapture)6673         virtual void setResultCapture( IResultCapture* resultCapture ) {
6674             m_resultCapture = resultCapture;
6675         }
setRunner(IRunner * runner)6676         virtual void setRunner( IRunner* runner ) {
6677             m_runner = runner;
6678         }
setConfig(Ptr<IConfig const> const & config)6679         virtual void setConfig( Ptr<IConfig const> const& config ) {
6680             m_config = config;
6681         }
6682 
6683         friend IMutableContext& getCurrentMutableContext();
6684 
6685     private:
findGeneratorsForCurrentTest()6686         IGeneratorsForTest* findGeneratorsForCurrentTest() {
6687             std::string testName = getResultCapture()->getCurrentTestName();
6688 
6689             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
6690                 m_generatorsByTestName.find( testName );
6691             return it != m_generatorsByTestName.end()
6692                 ? it->second
6693                 : CATCH_NULL;
6694         }
6695 
getGeneratorsForCurrentTest()6696         IGeneratorsForTest& getGeneratorsForCurrentTest() {
6697             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6698             if( !generators ) {
6699                 std::string testName = getResultCapture()->getCurrentTestName();
6700                 generators = createGeneratorsForTest();
6701                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
6702             }
6703             return *generators;
6704         }
6705 
6706     private:
6707         Ptr<IConfig const> m_config;
6708         IRunner* m_runner;
6709         IResultCapture* m_resultCapture;
6710         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
6711     };
6712 
6713     namespace {
6714         Context* currentContext = CATCH_NULL;
6715     }
getCurrentMutableContext()6716     IMutableContext& getCurrentMutableContext() {
6717         if( !currentContext )
6718             currentContext = new Context();
6719         return *currentContext;
6720     }
getCurrentContext()6721     IContext& getCurrentContext() {
6722         return getCurrentMutableContext();
6723     }
6724 
cleanUpContext()6725     void cleanUpContext() {
6726         delete currentContext;
6727         currentContext = CATCH_NULL;
6728     }
6729 }
6730 
6731 // #included from: catch_console_colour_impl.hpp
6732 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
6733 
6734 namespace Catch {
6735     namespace {
6736 
6737         struct IColourImpl {
~IColourImplCatch::__anon5febd4dc0411::IColourImpl6738             virtual ~IColourImpl() {}
6739             virtual void use( Colour::Code _colourCode ) = 0;
6740         };
6741 
6742         struct NoColourImpl : IColourImpl {
useCatch::__anon5febd4dc0411::NoColourImpl6743             void use( Colour::Code ) {}
6744 
instanceCatch::__anon5febd4dc0411::NoColourImpl6745             static IColourImpl* instance() {
6746                 static NoColourImpl s_instance;
6747                 return &s_instance;
6748             }
6749         };
6750 
6751     } // anon namespace
6752 } // namespace Catch
6753 
6754 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
6755 #   ifdef CATCH_PLATFORM_WINDOWS
6756 #       define CATCH_CONFIG_COLOUR_WINDOWS
6757 #   else
6758 #       define CATCH_CONFIG_COLOUR_ANSI
6759 #   endif
6760 #endif
6761 
6762 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
6763 
6764 #ifndef NOMINMAX
6765 #define NOMINMAX
6766 #endif
6767 
6768 #ifdef __AFXDLL
6769 #include <AfxWin.h>
6770 #else
6771 #include <windows.h>
6772 #endif
6773 
6774 namespace Catch {
6775 namespace {
6776 
6777     class Win32ColourImpl : public IColourImpl {
6778     public:
Win32ColourImpl()6779         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
6780         {
6781             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
6782             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
6783             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
6784             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
6785         }
6786 
use(Colour::Code _colourCode)6787         virtual void use( Colour::Code _colourCode ) {
6788             switch( _colourCode ) {
6789                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
6790                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6791                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
6792                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
6793                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
6794                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
6795                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
6796                 case Colour::Grey:      return setTextAttribute( 0 );
6797 
6798                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
6799                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
6800                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
6801                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6802 
6803                 case Colour::Bright: throw std::logic_error( "not a colour" );
6804             }
6805         }
6806 
6807     private:
setTextAttribute(WORD _textAttribute)6808         void setTextAttribute( WORD _textAttribute ) {
6809             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
6810         }
6811         HANDLE stdoutHandle;
6812         WORD originalForegroundAttributes;
6813         WORD originalBackgroundAttributes;
6814     };
6815 
platformColourInstance()6816     IColourImpl* platformColourInstance() {
6817         static Win32ColourImpl s_instance;
6818         return &s_instance;
6819     }
6820 
6821 } // end anon namespace
6822 } // end namespace Catch
6823 
6824 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
6825 
6826 #include <unistd.h>
6827 
6828 namespace Catch {
6829 namespace {
6830 
6831     // use POSIX/ ANSI console terminal codes
6832     // Thanks to Adam Strzelecki for original contribution
6833     // (http://github.com/nanoant)
6834     // https://github.com/philsquared/Catch/pull/131
6835     class PosixColourImpl : public IColourImpl {
6836     public:
use(Colour::Code _colourCode)6837         virtual void use( Colour::Code _colourCode ) {
6838             switch( _colourCode ) {
6839                 case Colour::None:
6840                 case Colour::White:     return setColour( "[0m" );
6841                 case Colour::Red:       return setColour( "[0;31m" );
6842                 case Colour::Green:     return setColour( "[0;32m" );
6843                 case Colour::Blue:      return setColour( "[0:34m" );
6844                 case Colour::Cyan:      return setColour( "[0;36m" );
6845                 case Colour::Yellow:    return setColour( "[0;33m" );
6846                 case Colour::Grey:      return setColour( "[1;30m" );
6847 
6848                 case Colour::LightGrey:     return setColour( "[0;37m" );
6849                 case Colour::BrightRed:     return setColour( "[1;31m" );
6850                 case Colour::BrightGreen:   return setColour( "[1;32m" );
6851                 case Colour::BrightWhite:   return setColour( "[1;37m" );
6852 
6853                 case Colour::Bright: throw std::logic_error( "not a colour" );
6854             }
6855         }
instance()6856         static IColourImpl* instance() {
6857             static PosixColourImpl s_instance;
6858             return &s_instance;
6859         }
6860 
6861     private:
setColour(const char * _escapeCode)6862         void setColour( const char* _escapeCode ) {
6863             Catch::cout() << '\033' << _escapeCode;
6864         }
6865     };
6866 
platformColourInstance()6867     IColourImpl* platformColourInstance() {
6868         Ptr<IConfig const> config = getCurrentContext().getConfig();
6869         return (config && config->forceColour()) || isatty(STDOUT_FILENO)
6870             ? PosixColourImpl::instance()
6871             : NoColourImpl::instance();
6872     }
6873 
6874 } // end anon namespace
6875 } // end namespace Catch
6876 
6877 #else  // not Windows or ANSI ///////////////////////////////////////////////
6878 
6879 namespace Catch {
6880 
platformColourInstance()6881     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
6882 
6883 } // end namespace Catch
6884 
6885 #endif // Windows/ ANSI/ None
6886 
6887 namespace Catch {
6888 
Colour(Code _colourCode)6889     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
Colour(Colour const & _other)6890     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
~Colour()6891     Colour::~Colour(){ if( !m_moved ) use( None ); }
6892 
use(Code _colourCode)6893     void Colour::use( Code _colourCode ) {
6894         static IColourImpl* impl = isDebuggerActive()
6895             ? NoColourImpl::instance()
6896             : platformColourInstance();
6897         impl->use( _colourCode );
6898     }
6899 
6900 } // end namespace Catch
6901 
6902 // #included from: catch_generators_impl.hpp
6903 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
6904 
6905 #include <vector>
6906 #include <string>
6907 #include <map>
6908 
6909 namespace Catch {
6910 
6911     struct GeneratorInfo : IGeneratorInfo {
6912 
GeneratorInfoCatch::GeneratorInfo6913         GeneratorInfo( std::size_t size )
6914         :   m_size( size ),
6915             m_currentIndex( 0 )
6916         {}
6917 
moveNextCatch::GeneratorInfo6918         bool moveNext() {
6919             if( ++m_currentIndex == m_size ) {
6920                 m_currentIndex = 0;
6921                 return false;
6922             }
6923             return true;
6924         }
6925 
getCurrentIndexCatch::GeneratorInfo6926         std::size_t getCurrentIndex() const {
6927             return m_currentIndex;
6928         }
6929 
6930         std::size_t m_size;
6931         std::size_t m_currentIndex;
6932     };
6933 
6934     ///////////////////////////////////////////////////////////////////////////
6935 
6936     class GeneratorsForTest : public IGeneratorsForTest {
6937 
6938     public:
~GeneratorsForTest()6939         ~GeneratorsForTest() {
6940             deleteAll( m_generatorsInOrder );
6941         }
6942 
getGeneratorInfo(std::string const & fileInfo,std::size_t size)6943         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
6944             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
6945             if( it == m_generatorsByName.end() ) {
6946                 IGeneratorInfo* info = new GeneratorInfo( size );
6947                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
6948                 m_generatorsInOrder.push_back( info );
6949                 return *info;
6950             }
6951             return *it->second;
6952         }
6953 
moveNext()6954         bool moveNext() {
6955             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
6956             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
6957             for(; it != itEnd; ++it ) {
6958                 if( (*it)->moveNext() )
6959                     return true;
6960             }
6961             return false;
6962         }
6963 
6964     private:
6965         std::map<std::string, IGeneratorInfo*> m_generatorsByName;
6966         std::vector<IGeneratorInfo*> m_generatorsInOrder;
6967     };
6968 
createGeneratorsForTest()6969     IGeneratorsForTest* createGeneratorsForTest()
6970     {
6971         return new GeneratorsForTest();
6972     }
6973 
6974 } // end namespace Catch
6975 
6976 // #included from: catch_assertionresult.hpp
6977 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
6978 
6979 namespace Catch {
6980 
AssertionInfo(std::string const & _macroName,SourceLineInfo const & _lineInfo,std::string const & _capturedExpression,ResultDisposition::Flags _resultDisposition)6981     AssertionInfo::AssertionInfo(   std::string const& _macroName,
6982                                     SourceLineInfo const& _lineInfo,
6983                                     std::string const& _capturedExpression,
6984                                     ResultDisposition::Flags _resultDisposition )
6985     :   macroName( _macroName ),
6986         lineInfo( _lineInfo ),
6987         capturedExpression( _capturedExpression ),
6988         resultDisposition( _resultDisposition )
6989     {}
6990 
AssertionResult()6991     AssertionResult::AssertionResult() {}
6992 
AssertionResult(AssertionInfo const & info,AssertionResultData const & data)6993     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
6994     :   m_info( info ),
6995         m_resultData( data )
6996     {}
6997 
~AssertionResult()6998     AssertionResult::~AssertionResult() {}
6999 
7000     // Result was a success
succeeded() const7001     bool AssertionResult::succeeded() const {
7002         return Catch::isOk( m_resultData.resultType );
7003     }
7004 
7005     // Result was a success, or failure is suppressed
isOk() const7006     bool AssertionResult::isOk() const {
7007         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
7008     }
7009 
getResultType() const7010     ResultWas::OfType AssertionResult::getResultType() const {
7011         return m_resultData.resultType;
7012     }
7013 
hasExpression() const7014     bool AssertionResult::hasExpression() const {
7015         return !m_info.capturedExpression.empty();
7016     }
7017 
hasMessage() const7018     bool AssertionResult::hasMessage() const {
7019         return !m_resultData.message.empty();
7020     }
7021 
getExpression() const7022     std::string AssertionResult::getExpression() const {
7023         if( isFalseTest( m_info.resultDisposition ) )
7024             return "!" + m_info.capturedExpression;
7025         else
7026             return m_info.capturedExpression;
7027     }
getExpressionInMacro() const7028     std::string AssertionResult::getExpressionInMacro() const {
7029         if( m_info.macroName.empty() )
7030             return m_info.capturedExpression;
7031         else
7032             return m_info.macroName + "( " + m_info.capturedExpression + " )";
7033     }
7034 
hasExpandedExpression() const7035     bool AssertionResult::hasExpandedExpression() const {
7036         return hasExpression() && getExpandedExpression() != getExpression();
7037     }
7038 
getExpandedExpression() const7039     std::string AssertionResult::getExpandedExpression() const {
7040         return m_resultData.reconstructedExpression;
7041     }
7042 
getMessage() const7043     std::string AssertionResult::getMessage() const {
7044         return m_resultData.message;
7045     }
getSourceInfo() const7046     SourceLineInfo AssertionResult::getSourceInfo() const {
7047         return m_info.lineInfo;
7048     }
7049 
getTestMacroName() const7050     std::string AssertionResult::getTestMacroName() const {
7051         return m_info.macroName;
7052     }
7053 
7054 } // end namespace Catch
7055 
7056 // #included from: catch_test_case_info.hpp
7057 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
7058 
7059 namespace Catch {
7060 
parseSpecialTag(std::string const & tag)7061     inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
7062         if( startsWith( tag, "." ) ||
7063             tag == "hide" ||
7064             tag == "!hide" )
7065             return TestCaseInfo::IsHidden;
7066         else if( tag == "!throws" )
7067             return TestCaseInfo::Throws;
7068         else if( tag == "!shouldfail" )
7069             return TestCaseInfo::ShouldFail;
7070         else if( tag == "!mayfail" )
7071             return TestCaseInfo::MayFail;
7072         else
7073             return TestCaseInfo::None;
7074     }
isReservedTag(std::string const & tag)7075     inline bool isReservedTag( std::string const& tag ) {
7076         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
7077     }
enforceNotReservedTag(std::string const & tag,SourceLineInfo const & _lineInfo)7078     inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
7079         if( isReservedTag( tag ) ) {
7080             {
7081                 Colour colourGuard( Colour::Red );
7082                 Catch::cerr()
7083                     << "Tag name [" << tag << "] not allowed.\n"
7084                     << "Tag names starting with non alpha-numeric characters are reserved\n";
7085             }
7086             {
7087                 Colour colourGuard( Colour::FileName );
7088                 Catch::cerr() << _lineInfo << std::endl;
7089             }
7090             exit(1);
7091         }
7092     }
7093 
makeTestCase(ITestCase * _testCase,std::string const & _className,std::string const & _name,std::string const & _descOrTags,SourceLineInfo const & _lineInfo)7094     TestCase makeTestCase(  ITestCase* _testCase,
7095                             std::string const& _className,
7096                             std::string const& _name,
7097                             std::string const& _descOrTags,
7098                             SourceLineInfo const& _lineInfo )
7099     {
7100         bool isHidden( startsWith( _name, "./" ) ); // Legacy support
7101 
7102         // Parse out tags
7103         std::set<std::string> tags;
7104         std::string desc, tag;
7105         bool inTag = false;
7106         for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
7107             char c = _descOrTags[i];
7108             if( !inTag ) {
7109                 if( c == '[' )
7110                     inTag = true;
7111                 else
7112                     desc += c;
7113             }
7114             else {
7115                 if( c == ']' ) {
7116                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
7117                     if( prop == TestCaseInfo::IsHidden )
7118                         isHidden = true;
7119                     else if( prop == TestCaseInfo::None )
7120                         enforceNotReservedTag( tag, _lineInfo );
7121 
7122                     tags.insert( tag );
7123                     tag.clear();
7124                     inTag = false;
7125                 }
7126                 else
7127                     tag += c;
7128             }
7129         }
7130         if( isHidden ) {
7131             tags.insert( "hide" );
7132             tags.insert( "." );
7133         }
7134 
7135         TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
7136         return TestCase( _testCase, info );
7137     }
7138 
setTags(TestCaseInfo & testCaseInfo,std::set<std::string> const & tags)7139     void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
7140     {
7141         testCaseInfo.tags = tags;
7142         testCaseInfo.lcaseTags.clear();
7143 
7144         std::ostringstream oss;
7145         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
7146             oss << "[" << *it << "]";
7147             std::string lcaseTag = toLower( *it );
7148             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
7149             testCaseInfo.lcaseTags.insert( lcaseTag );
7150         }
7151         testCaseInfo.tagsAsString = oss.str();
7152     }
7153 
TestCaseInfo(std::string const & _name,std::string const & _className,std::string const & _description,std::set<std::string> const & _tags,SourceLineInfo const & _lineInfo)7154     TestCaseInfo::TestCaseInfo( std::string const& _name,
7155                                 std::string const& _className,
7156                                 std::string const& _description,
7157                                 std::set<std::string> const& _tags,
7158                                 SourceLineInfo const& _lineInfo )
7159     :   name( _name ),
7160         className( _className ),
7161         description( _description ),
7162         lineInfo( _lineInfo ),
7163         properties( None )
7164     {
7165         setTags( *this, _tags );
7166     }
7167 
TestCaseInfo(TestCaseInfo const & other)7168     TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
7169     :   name( other.name ),
7170         className( other.className ),
7171         description( other.description ),
7172         tags( other.tags ),
7173         lcaseTags( other.lcaseTags ),
7174         tagsAsString( other.tagsAsString ),
7175         lineInfo( other.lineInfo ),
7176         properties( other.properties )
7177     {}
7178 
isHidden() const7179     bool TestCaseInfo::isHidden() const {
7180         return ( properties & IsHidden ) != 0;
7181     }
throws() const7182     bool TestCaseInfo::throws() const {
7183         return ( properties & Throws ) != 0;
7184     }
okToFail() const7185     bool TestCaseInfo::okToFail() const {
7186         return ( properties & (ShouldFail | MayFail ) ) != 0;
7187     }
expectedToFail() const7188     bool TestCaseInfo::expectedToFail() const {
7189         return ( properties & (ShouldFail ) ) != 0;
7190     }
7191 
TestCase(ITestCase * testCase,TestCaseInfo const & info)7192     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
7193 
TestCase(TestCase const & other)7194     TestCase::TestCase( TestCase const& other )
7195     :   TestCaseInfo( other ),
7196         test( other.test )
7197     {}
7198 
withName(std::string const & _newName) const7199     TestCase TestCase::withName( std::string const& _newName ) const {
7200         TestCase other( *this );
7201         other.name = _newName;
7202         return other;
7203     }
7204 
swap(TestCase & other)7205     void TestCase::swap( TestCase& other ) {
7206         test.swap( other.test );
7207         name.swap( other.name );
7208         className.swap( other.className );
7209         description.swap( other.description );
7210         tags.swap( other.tags );
7211         lcaseTags.swap( other.lcaseTags );
7212         tagsAsString.swap( other.tagsAsString );
7213         std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
7214         std::swap( lineInfo, other.lineInfo );
7215     }
7216 
invoke() const7217     void TestCase::invoke() const {
7218         test->invoke();
7219     }
7220 
operator ==(TestCase const & other) const7221     bool TestCase::operator == ( TestCase const& other ) const {
7222         return  test.get() == other.test.get() &&
7223                 name == other.name &&
7224                 className == other.className;
7225     }
7226 
operator <(TestCase const & other) const7227     bool TestCase::operator < ( TestCase const& other ) const {
7228         return name < other.name;
7229     }
operator =(TestCase const & other)7230     TestCase& TestCase::operator = ( TestCase const& other ) {
7231         TestCase temp( other );
7232         swap( temp );
7233         return *this;
7234     }
7235 
getTestCaseInfo() const7236     TestCaseInfo const& TestCase::getTestCaseInfo() const
7237     {
7238         return *this;
7239     }
7240 
7241 } // end namespace Catch
7242 
7243 // #included from: catch_version.hpp
7244 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
7245 
7246 namespace Catch {
7247 
Version(unsigned int _majorVersion,unsigned int _minorVersion,unsigned int _patchNumber,std::string const & _branchName,unsigned int _buildNumber)7248     Version::Version
7249         (   unsigned int _majorVersion,
7250             unsigned int _minorVersion,
7251             unsigned int _patchNumber,
7252             std::string const& _branchName,
7253             unsigned int _buildNumber )
7254     :   majorVersion( _majorVersion ),
7255         minorVersion( _minorVersion ),
7256         patchNumber( _patchNumber ),
7257         branchName( _branchName ),
7258         buildNumber( _buildNumber )
7259     {}
7260 
operator <<(std::ostream & os,Version const & version)7261     std::ostream& operator << ( std::ostream& os, Version const& version ) {
7262         os  << version.majorVersion << "."
7263             << version.minorVersion << "."
7264             << version.patchNumber;
7265 
7266         if( !version.branchName.empty() ) {
7267             os  << "-" << version.branchName
7268                 << "." << version.buildNumber;
7269         }
7270         return os;
7271     }
7272 
7273     Version libraryVersion( 1, 3, 1, "", 0 );
7274 
7275 }
7276 
7277 // #included from: catch_message.hpp
7278 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
7279 
7280 namespace Catch {
7281 
MessageInfo(std::string const & _macroName,SourceLineInfo const & _lineInfo,ResultWas::OfType _type)7282     MessageInfo::MessageInfo(   std::string const& _macroName,
7283                                 SourceLineInfo const& _lineInfo,
7284                                 ResultWas::OfType _type )
7285     :   macroName( _macroName ),
7286         lineInfo( _lineInfo ),
7287         type( _type ),
7288         sequence( ++globalCount )
7289     {}
7290 
7291     // This may need protecting if threading support is added
7292     unsigned int MessageInfo::globalCount = 0;
7293 
7294     ////////////////////////////////////////////////////////////////////////////
7295 
ScopedMessage(MessageBuilder const & builder)7296     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
7297     : m_info( builder.m_info )
7298     {
7299         m_info.message = builder.m_stream.str();
7300         getResultCapture().pushScopedMessage( m_info );
7301     }
ScopedMessage(ScopedMessage const & other)7302     ScopedMessage::ScopedMessage( ScopedMessage const& other )
7303     : m_info( other.m_info )
7304     {}
7305 
~ScopedMessage()7306     ScopedMessage::~ScopedMessage() {
7307         getResultCapture().popScopedMessage( m_info );
7308     }
7309 
7310 } // end namespace Catch
7311 
7312 // #included from: catch_legacy_reporter_adapter.hpp
7313 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
7314 
7315 // #included from: catch_legacy_reporter_adapter.h
7316 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
7317 
7318 namespace Catch
7319 {
7320     // Deprecated
7321     struct IReporter : IShared {
7322         virtual ~IReporter();
7323 
7324         virtual bool shouldRedirectStdout() const = 0;
7325 
7326         virtual void StartTesting() = 0;
7327         virtual void EndTesting( Totals const& totals ) = 0;
7328         virtual void StartGroup( std::string const& groupName ) = 0;
7329         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
7330         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
7331         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
7332         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
7333         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
7334         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
7335         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
7336         virtual void Aborted() = 0;
7337         virtual void Result( AssertionResult const& result ) = 0;
7338     };
7339 
7340     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
7341     {
7342     public:
7343         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
7344         virtual ~LegacyReporterAdapter();
7345 
7346         virtual ReporterPreferences getPreferences() const;
7347         virtual void noMatchingTestCases( std::string const& );
7348         virtual void testRunStarting( TestRunInfo const& );
7349         virtual void testGroupStarting( GroupInfo const& groupInfo );
7350         virtual void testCaseStarting( TestCaseInfo const& testInfo );
7351         virtual void sectionStarting( SectionInfo const& sectionInfo );
7352         virtual void assertionStarting( AssertionInfo const& );
7353         virtual bool assertionEnded( AssertionStats const& assertionStats );
7354         virtual void sectionEnded( SectionStats const& sectionStats );
7355         virtual void testCaseEnded( TestCaseStats const& testCaseStats );
7356         virtual void testGroupEnded( TestGroupStats const& testGroupStats );
7357         virtual void testRunEnded( TestRunStats const& testRunStats );
7358         virtual void skipTest( TestCaseInfo const& );
7359 
7360     private:
7361         Ptr<IReporter> m_legacyReporter;
7362     };
7363 }
7364 
7365 namespace Catch
7366 {
LegacyReporterAdapter(Ptr<IReporter> const & legacyReporter)7367     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
7368     :   m_legacyReporter( legacyReporter )
7369     {}
~LegacyReporterAdapter()7370     LegacyReporterAdapter::~LegacyReporterAdapter() {}
7371 
getPreferences() const7372     ReporterPreferences LegacyReporterAdapter::getPreferences() const {
7373         ReporterPreferences prefs;
7374         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
7375         return prefs;
7376     }
7377 
noMatchingTestCases(std::string const &)7378     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
testRunStarting(TestRunInfo const &)7379     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
7380         m_legacyReporter->StartTesting();
7381     }
testGroupStarting(GroupInfo const & groupInfo)7382     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
7383         m_legacyReporter->StartGroup( groupInfo.name );
7384     }
testCaseStarting(TestCaseInfo const & testInfo)7385     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
7386         m_legacyReporter->StartTestCase( testInfo );
7387     }
sectionStarting(SectionInfo const & sectionInfo)7388     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
7389         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
7390     }
assertionStarting(AssertionInfo const &)7391     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
7392         // Not on legacy interface
7393     }
7394 
assertionEnded(AssertionStats const & assertionStats)7395     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
7396         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
7397             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
7398                     it != itEnd;
7399                     ++it ) {
7400                 if( it->type == ResultWas::Info ) {
7401                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
7402                     rb << it->message;
7403                     rb.setResultType( ResultWas::Info );
7404                     AssertionResult result = rb.build();
7405                     m_legacyReporter->Result( result );
7406                 }
7407             }
7408         }
7409         m_legacyReporter->Result( assertionStats.assertionResult );
7410         return true;
7411     }
sectionEnded(SectionStats const & sectionStats)7412     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
7413         if( sectionStats.missingAssertions )
7414             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
7415         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
7416     }
testCaseEnded(TestCaseStats const & testCaseStats)7417     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
7418         m_legacyReporter->EndTestCase
7419             (   testCaseStats.testInfo,
7420                 testCaseStats.totals,
7421                 testCaseStats.stdOut,
7422                 testCaseStats.stdErr );
7423     }
testGroupEnded(TestGroupStats const & testGroupStats)7424     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
7425         if( testGroupStats.aborting )
7426             m_legacyReporter->Aborted();
7427         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
7428     }
testRunEnded(TestRunStats const & testRunStats)7429     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
7430         m_legacyReporter->EndTesting( testRunStats.totals );
7431     }
skipTest(TestCaseInfo const &)7432     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
7433     }
7434 }
7435 
7436 // #included from: catch_timer.hpp
7437 
7438 #ifdef __clang__
7439 #pragma clang diagnostic push
7440 #pragma clang diagnostic ignored "-Wc++11-long-long"
7441 #endif
7442 
7443 #ifdef CATCH_PLATFORM_WINDOWS
7444 #include <windows.h>
7445 #else
7446 #include <sys/time.h>
7447 #endif
7448 
7449 namespace Catch {
7450 
7451     namespace {
7452 #ifdef CATCH_PLATFORM_WINDOWS
getCurrentTicks()7453         uint64_t getCurrentTicks() {
7454             static uint64_t hz=0, hzo=0;
7455             if (!hz) {
7456                 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
7457                 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
7458             }
7459             uint64_t t;
7460             QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
7461             return ((t-hzo)*1000000)/hz;
7462         }
7463 #else
7464         uint64_t getCurrentTicks() {
7465             timeval t;
7466             gettimeofday(&t,CATCH_NULL);
7467             return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
7468         }
7469 #endif
7470     }
7471 
start()7472     void Timer::start() {
7473         m_ticks = getCurrentTicks();
7474     }
getElapsedMicroseconds() const7475     unsigned int Timer::getElapsedMicroseconds() const {
7476         return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
7477     }
getElapsedMilliseconds() const7478     unsigned int Timer::getElapsedMilliseconds() const {
7479         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
7480     }
getElapsedSeconds() const7481     double Timer::getElapsedSeconds() const {
7482         return getElapsedMicroseconds()/1000000.0;
7483     }
7484 
7485 } // namespace Catch
7486 
7487 #ifdef __clang__
7488 #pragma clang diagnostic pop
7489 #endif
7490 // #included from: catch_common.hpp
7491 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
7492 
7493 namespace Catch {
7494 
startsWith(std::string const & s,std::string const & prefix)7495     bool startsWith( std::string const& s, std::string const& prefix ) {
7496         return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
7497     }
endsWith(std::string const & s,std::string const & suffix)7498     bool endsWith( std::string const& s, std::string const& suffix ) {
7499         return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
7500     }
contains(std::string const & s,std::string const & infix)7501     bool contains( std::string const& s, std::string const& infix ) {
7502         return s.find( infix ) != std::string::npos;
7503     }
toLowerInPlace(std::string & s)7504     void toLowerInPlace( std::string& s ) {
7505         std::transform( s.begin(), s.end(), s.begin(), ::tolower );
7506     }
toLower(std::string const & s)7507     std::string toLower( std::string const& s ) {
7508         std::string lc = s;
7509         toLowerInPlace( lc );
7510         return lc;
7511     }
trim(std::string const & str)7512     std::string trim( std::string const& str ) {
7513         static char const* whitespaceChars = "\n\r\t ";
7514         std::string::size_type start = str.find_first_not_of( whitespaceChars );
7515         std::string::size_type end = str.find_last_not_of( whitespaceChars );
7516 
7517         return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
7518     }
7519 
replaceInPlace(std::string & str,std::string const & replaceThis,std::string const & withThis)7520     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
7521         bool replaced = false;
7522         std::size_t i = str.find( replaceThis );
7523         while( i != std::string::npos ) {
7524             replaced = true;
7525             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7526             if( i < str.size()-withThis.size() )
7527                 i = str.find( replaceThis, i+withThis.size() );
7528             else
7529                 i = std::string::npos;
7530         }
7531         return replaced;
7532     }
7533 
pluralise(std::size_t count,std::string const & label)7534     pluralise::pluralise( std::size_t count, std::string const& label )
7535     :   m_count( count ),
7536         m_label( label )
7537     {}
7538 
operator <<(std::ostream & os,pluralise const & pluraliser)7539     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
7540         os << pluraliser.m_count << " " << pluraliser.m_label;
7541         if( pluraliser.m_count != 1 )
7542             os << "s";
7543         return os;
7544     }
7545 
SourceLineInfo()7546     SourceLineInfo::SourceLineInfo() : line( 0 ){}
SourceLineInfo(char const * _file,std::size_t _line)7547     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
7548     :   file( _file ),
7549         line( _line )
7550     {}
SourceLineInfo(SourceLineInfo const & other)7551     SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
7552     :   file( other.file ),
7553         line( other.line )
7554     {}
empty() const7555     bool SourceLineInfo::empty() const {
7556         return file.empty();
7557     }
operator ==(SourceLineInfo const & other) const7558     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
7559         return line == other.line && file == other.file;
7560     }
operator <(SourceLineInfo const & other) const7561     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
7562         return line < other.line || ( line == other.line  && file < other.file );
7563     }
7564 
seedRng(IConfig const & config)7565     void seedRng( IConfig const& config ) {
7566         if( config.rngSeed() != 0 )
7567             std::srand( config.rngSeed() );
7568     }
rngSeed()7569     unsigned int rngSeed() {
7570         return getCurrentContext().getConfig()->rngSeed();
7571     }
7572 
operator <<(std::ostream & os,SourceLineInfo const & info)7573     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7574 #ifndef __GNUG__
7575         os << info.file << "(" << info.line << ")";
7576 #else
7577         os << info.file << ":" << info.line;
7578 #endif
7579         return os;
7580     }
7581 
throwLogicError(std::string const & message,SourceLineInfo const & locationInfo)7582     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
7583         std::ostringstream oss;
7584         oss << locationInfo << ": Internal Catch error: '" << message << "'";
7585         if( alwaysTrue() )
7586             throw std::logic_error( oss.str() );
7587     }
7588 }
7589 
7590 // #included from: catch_section.hpp
7591 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
7592 
7593 namespace Catch {
7594 
SectionInfo(SourceLineInfo const & _lineInfo,std::string const & _name,std::string const & _description)7595     SectionInfo::SectionInfo
7596         (   SourceLineInfo const& _lineInfo,
7597             std::string const& _name,
7598             std::string const& _description )
7599     :   name( _name ),
7600         description( _description ),
7601         lineInfo( _lineInfo )
7602     {}
7603 
Section(SectionInfo const & info)7604     Section::Section( SectionInfo const& info )
7605     :   m_info( info ),
7606         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
7607     {
7608         m_timer.start();
7609     }
7610 
~Section()7611     Section::~Section() {
7612         if( m_sectionIncluded ) {
7613             SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
7614             if( std::uncaught_exception() )
7615                 getResultCapture().sectionEndedEarly( endInfo );
7616             else
7617                 getResultCapture().sectionEnded( endInfo );
7618         }
7619     }
7620 
7621     // This indicates whether the section should be executed or not
operator bool() const7622     Section::operator bool() const {
7623         return m_sectionIncluded;
7624     }
7625 
7626 } // end namespace Catch
7627 
7628 // #included from: catch_debugger.hpp
7629 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
7630 
7631 #include <iostream>
7632 
7633 #ifdef CATCH_PLATFORM_MAC
7634 
7635     #include <assert.h>
7636     #include <stdbool.h>
7637     #include <sys/types.h>
7638     #include <unistd.h>
7639     #include <sys/sysctl.h>
7640 
7641     namespace Catch{
7642 
7643         // The following function is taken directly from the following technical note:
7644         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7645 
7646         // Returns true if the current process is being debugged (either
7647         // running under the debugger or has a debugger attached post facto).
isDebuggerActive()7648         bool isDebuggerActive(){
7649 
7650             int                 mib[4];
7651             struct kinfo_proc   info;
7652             size_t              size;
7653 
7654             // Initialize the flags so that, if sysctl fails for some bizarre
7655             // reason, we get a predictable result.
7656 
7657             info.kp_proc.p_flag = 0;
7658 
7659             // Initialize mib, which tells sysctl the info we want, in this case
7660             // we're looking for information about a specific process ID.
7661 
7662             mib[0] = CTL_KERN;
7663             mib[1] = KERN_PROC;
7664             mib[2] = KERN_PROC_PID;
7665             mib[3] = getpid();
7666 
7667             // Call sysctl.
7668 
7669             size = sizeof(info);
7670             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
7671                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7672                 return false;
7673             }
7674 
7675             // We're being debugged if the P_TRACED flag is set.
7676 
7677             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7678         }
7679     } // namespace Catch
7680 
7681 #elif defined(_MSC_VER)
7682     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7683     namespace Catch {
isDebuggerActive()7684         bool isDebuggerActive() {
7685             return IsDebuggerPresent() != 0;
7686         }
7687     }
7688 #elif defined(__MINGW32__)
7689     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7690     namespace Catch {
isDebuggerActive()7691         bool isDebuggerActive() {
7692             return IsDebuggerPresent() != 0;
7693         }
7694     }
7695 #else
7696     namespace Catch {
isDebuggerActive()7697        inline bool isDebuggerActive() { return false; }
7698     }
7699 #endif // Platform
7700 
7701 #ifdef CATCH_PLATFORM_WINDOWS
7702     extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
7703     namespace Catch {
writeToDebugConsole(std::string const & text)7704         void writeToDebugConsole( std::string const& text ) {
7705             ::OutputDebugStringA( text.c_str() );
7706         }
7707     }
7708 #else
7709     namespace Catch {
writeToDebugConsole(std::string const & text)7710         void writeToDebugConsole( std::string const& text ) {
7711             // !TBD: Need a version for Mac/ XCode and other IDEs
7712             Catch::cout() << text;
7713         }
7714     }
7715 #endif // Platform
7716 
7717 // #included from: catch_tostring.hpp
7718 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
7719 
7720 namespace Catch {
7721 
7722 namespace Detail {
7723 
7724     const std::string unprintableString = "{?}";
7725 
7726     namespace {
7727         const int hexThreshold = 255;
7728 
7729         struct Endianness {
7730             enum Arch { Big, Little };
7731 
whichCatch::Detail::__anon5febd4dc0811::Endianness7732             static Arch which() {
7733                 union _{
7734                     int asInt;
7735                     char asChar[sizeof (int)];
7736                 } u;
7737 
7738                 u.asInt = 1;
7739                 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
7740             }
7741         };
7742     }
7743 
rawMemoryToString(const void * object,std::size_t size)7744     std::string rawMemoryToString( const void *object, std::size_t size )
7745     {
7746         // Reverse order for little endian architectures
7747         int i = 0, end = static_cast<int>( size ), inc = 1;
7748         if( Endianness::which() == Endianness::Little ) {
7749             i = end-1;
7750             end = inc = -1;
7751         }
7752 
7753         unsigned char const *bytes = static_cast<unsigned char const *>(object);
7754         std::ostringstream os;
7755         os << "0x" << std::setfill('0') << std::hex;
7756         for( ; i != end; i += inc )
7757              os << std::setw(2) << static_cast<unsigned>(bytes[i]);
7758        return os.str();
7759     }
7760 }
7761 
toString(std::string const & value)7762 std::string toString( std::string const& value ) {
7763     std::string s = value;
7764     if( getCurrentContext().getConfig()->showInvisibles() ) {
7765         for(size_t i = 0; i < s.size(); ++i ) {
7766             std::string subs;
7767             switch( s[i] ) {
7768             case '\n': subs = "\\n"; break;
7769             case '\t': subs = "\\t"; break;
7770             default: break;
7771             }
7772             if( !subs.empty() ) {
7773                 s = s.substr( 0, i ) + subs + s.substr( i+1 );
7774                 ++i;
7775             }
7776         }
7777     }
7778     return "\"" + s + "\"";
7779 }
toString(std::wstring const & value)7780 std::string toString( std::wstring const& value ) {
7781 
7782     std::string s;
7783     s.reserve( value.size() );
7784     for(size_t i = 0; i < value.size(); ++i )
7785         s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
7786     return Catch::toString( s );
7787 }
7788 
toString(const char * const value)7789 std::string toString( const char* const value ) {
7790     return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
7791 }
7792 
toString(char * const value)7793 std::string toString( char* const value ) {
7794     return Catch::toString( static_cast<const char*>( value ) );
7795 }
7796 
toString(const wchar_t * const value)7797 std::string toString( const wchar_t* const value )
7798 {
7799 	return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
7800 }
7801 
toString(wchar_t * const value)7802 std::string toString( wchar_t* const value )
7803 {
7804 	return Catch::toString( static_cast<const wchar_t*>( value ) );
7805 }
7806 
toString(int value)7807 std::string toString( int value ) {
7808     std::ostringstream oss;
7809     oss << value;
7810     if( value > Detail::hexThreshold )
7811         oss << " (0x" << std::hex << value << ")";
7812     return oss.str();
7813 }
7814 
toString(unsigned long value)7815 std::string toString( unsigned long value ) {
7816     std::ostringstream oss;
7817     oss << value;
7818     if( value > Detail::hexThreshold )
7819         oss << " (0x" << std::hex << value << ")";
7820     return oss.str();
7821 }
7822 
toString(unsigned int value)7823 std::string toString( unsigned int value ) {
7824     return Catch::toString( static_cast<unsigned long>( value ) );
7825 }
7826 
7827 template<typename T>
fpToString(T value,int precision)7828 std::string fpToString( T value, int precision ) {
7829     std::ostringstream oss;
7830     oss << std::setprecision( precision )
7831         << std::fixed
7832         << value;
7833     std::string d = oss.str();
7834     std::size_t i = d.find_last_not_of( '0' );
7835     if( i != std::string::npos && i != d.size()-1 ) {
7836         if( d[i] == '.' )
7837             i++;
7838         d = d.substr( 0, i+1 );
7839     }
7840     return d;
7841 }
7842 
toString(const double value)7843 std::string toString( const double value ) {
7844     return fpToString( value, 10 );
7845 }
toString(const float value)7846 std::string toString( const float value ) {
7847     return fpToString( value, 5 ) + "f";
7848 }
7849 
toString(bool value)7850 std::string toString( bool value ) {
7851     return value ? "true" : "false";
7852 }
7853 
toString(char value)7854 std::string toString( char value ) {
7855     return value < ' '
7856         ? toString( static_cast<unsigned int>( value ) )
7857         : Detail::makeString( value );
7858 }
7859 
toString(signed char value)7860 std::string toString( signed char value ) {
7861     return toString( static_cast<char>( value ) );
7862 }
7863 
toString(unsigned char value)7864 std::string toString( unsigned char value ) {
7865     return toString( static_cast<char>( value ) );
7866 }
7867 
7868 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
toString(long long value)7869 std::string toString( long long value ) {
7870     std::ostringstream oss;
7871     oss << value;
7872     if( value > Detail::hexThreshold )
7873         oss << " (0x" << std::hex << value << ")";
7874     return oss.str();
7875 }
toString(unsigned long long value)7876 std::string toString( unsigned long long value ) {
7877     std::ostringstream oss;
7878     oss << value;
7879     if( value > Detail::hexThreshold )
7880         oss << " (0x" << std::hex << value << ")";
7881     return oss.str();
7882 }
7883 #endif
7884 
7885 #ifdef CATCH_CONFIG_CPP11_NULLPTR
toString(std::nullptr_t)7886 std::string toString( std::nullptr_t ) {
7887     return "nullptr";
7888 }
7889 #endif
7890 
7891 #ifdef __OBJC__
toString(NSString const * const & nsstring)7892     std::string toString( NSString const * const& nsstring ) {
7893         if( !nsstring )
7894             return "nil";
7895         return "@" + toString([nsstring UTF8String]);
7896     }
toString(NSString * CATCH_ARC_STRONG const & nsstring)7897     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
7898         if( !nsstring )
7899             return "nil";
7900         return "@" + toString([nsstring UTF8String]);
7901     }
toString(NSObject * const & nsObject)7902     std::string toString( NSObject* const& nsObject ) {
7903         return toString( [nsObject description] );
7904     }
7905 #endif
7906 
7907 } // end namespace Catch
7908 
7909 // #included from: catch_result_builder.hpp
7910 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
7911 
7912 namespace Catch {
7913 
capturedExpressionWithSecondArgument(std::string const & capturedExpression,std::string const & secondArg)7914     std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
7915         return secondArg.empty() || secondArg == "\"\""
7916             ? capturedExpression
7917             : capturedExpression + ", " + secondArg;
7918     }
ResultBuilder(char const * macroName,SourceLineInfo const & lineInfo,char const * capturedExpression,ResultDisposition::Flags resultDisposition,char const * secondArg)7919     ResultBuilder::ResultBuilder(   char const* macroName,
7920                                     SourceLineInfo const& lineInfo,
7921                                     char const* capturedExpression,
7922                                     ResultDisposition::Flags resultDisposition,
7923                                     char const* secondArg )
7924     :   m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
7925         m_shouldDebugBreak( false ),
7926         m_shouldThrow( false )
7927     {}
7928 
setResultType(ResultWas::OfType result)7929     ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
7930         m_data.resultType = result;
7931         return *this;
7932     }
setResultType(bool result)7933     ResultBuilder& ResultBuilder::setResultType( bool result ) {
7934         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
7935         return *this;
7936     }
setLhs(std::string const & lhs)7937     ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
7938         m_exprComponents.lhs = lhs;
7939         return *this;
7940     }
setRhs(std::string const & rhs)7941     ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
7942         m_exprComponents.rhs = rhs;
7943         return *this;
7944     }
setOp(std::string const & op)7945     ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
7946         m_exprComponents.op = op;
7947         return *this;
7948     }
7949 
endExpression()7950     void ResultBuilder::endExpression() {
7951         m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
7952         captureExpression();
7953     }
7954 
useActiveException(ResultDisposition::Flags resultDisposition)7955     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
7956         m_assertionInfo.resultDisposition = resultDisposition;
7957         m_stream.oss << Catch::translateActiveException();
7958         captureResult( ResultWas::ThrewException );
7959     }
7960 
captureResult(ResultWas::OfType resultType)7961     void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
7962         setResultType( resultType );
7963         captureExpression();
7964     }
captureExpectedException(std::string const & expectedMessage)7965     void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
7966         if( expectedMessage.empty() )
7967             captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
7968         else
7969             captureExpectedException( Matchers::Equals( expectedMessage ) );
7970     }
7971 
captureExpectedException(Matchers::Impl::Matcher<std::string> const & matcher)7972     void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
7973 
7974         assert( m_exprComponents.testFalse == false );
7975         AssertionResultData data = m_data;
7976         data.resultType = ResultWas::Ok;
7977         data.reconstructedExpression = m_assertionInfo.capturedExpression;
7978 
7979         std::string actualMessage = Catch::translateActiveException();
7980         if( !matcher.match( actualMessage ) ) {
7981             data.resultType = ResultWas::ExpressionFailed;
7982             data.reconstructedExpression = actualMessage;
7983         }
7984         AssertionResult result( m_assertionInfo, data );
7985         handleResult( result );
7986     }
7987 
captureExpression()7988     void ResultBuilder::captureExpression() {
7989         AssertionResult result = build();
7990         handleResult( result );
7991     }
handleResult(AssertionResult const & result)7992     void ResultBuilder::handleResult( AssertionResult const& result )
7993     {
7994         getResultCapture().assertionEnded( result );
7995 
7996         if( !result.isOk() ) {
7997             if( getCurrentContext().getConfig()->shouldDebugBreak() )
7998                 m_shouldDebugBreak = true;
7999             if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
8000                 m_shouldThrow = true;
8001         }
8002     }
react()8003     void ResultBuilder::react() {
8004         if( m_shouldThrow )
8005             throw Catch::TestFailureException();
8006     }
8007 
shouldDebugBreak() const8008     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
allowThrows() const8009     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
8010 
build() const8011     AssertionResult ResultBuilder::build() const
8012     {
8013         assert( m_data.resultType != ResultWas::Unknown );
8014 
8015         AssertionResultData data = m_data;
8016 
8017         // Flip bool results if testFalse is set
8018         if( m_exprComponents.testFalse ) {
8019             if( data.resultType == ResultWas::Ok )
8020                 data.resultType = ResultWas::ExpressionFailed;
8021             else if( data.resultType == ResultWas::ExpressionFailed )
8022                 data.resultType = ResultWas::Ok;
8023         }
8024 
8025         data.message = m_stream.oss.str();
8026         data.reconstructedExpression = reconstructExpression();
8027         if( m_exprComponents.testFalse ) {
8028             if( m_exprComponents.op == "" )
8029                 data.reconstructedExpression = "!" + data.reconstructedExpression;
8030             else
8031                 data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
8032         }
8033         return AssertionResult( m_assertionInfo, data );
8034     }
reconstructExpression() const8035     std::string ResultBuilder::reconstructExpression() const {
8036         if( m_exprComponents.op == "" )
8037             return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
8038         else if( m_exprComponents.op == "matches" )
8039             return m_exprComponents.lhs + " " + m_exprComponents.rhs;
8040         else if( m_exprComponents.op != "!" ) {
8041             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
8042                 m_exprComponents.lhs.find("\n") == std::string::npos &&
8043                 m_exprComponents.rhs.find("\n") == std::string::npos )
8044                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
8045             else
8046                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
8047         }
8048         else
8049             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}";
8050     }
8051 
8052 } // end namespace Catch
8053 
8054 // #included from: catch_tag_alias_registry.hpp
8055 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8056 
8057 // #included from: catch_tag_alias_registry.h
8058 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
8059 
8060 #include <map>
8061 
8062 namespace Catch {
8063 
8064     class TagAliasRegistry : public ITagAliasRegistry {
8065     public:
8066         virtual ~TagAliasRegistry();
8067         virtual Option<TagAlias> find( std::string const& alias ) const;
8068         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
8069         void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
8070         static TagAliasRegistry& get();
8071 
8072     private:
8073         std::map<std::string, TagAlias> m_registry;
8074     };
8075 
8076 } // end namespace Catch
8077 
8078 #include <map>
8079 #include <iostream>
8080 
8081 namespace Catch {
8082 
~TagAliasRegistry()8083     TagAliasRegistry::~TagAliasRegistry() {}
8084 
find(std::string const & alias) const8085     Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
8086         std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
8087         if( it != m_registry.end() )
8088             return it->second;
8089         else
8090             return Option<TagAlias>();
8091     }
8092 
expandAliases(std::string const & unexpandedTestSpec) const8093     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
8094         std::string expandedTestSpec = unexpandedTestSpec;
8095         for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
8096                 it != itEnd;
8097                 ++it ) {
8098             std::size_t pos = expandedTestSpec.find( it->first );
8099             if( pos != std::string::npos ) {
8100                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
8101                                     it->second.tag +
8102                                     expandedTestSpec.substr( pos + it->first.size() );
8103             }
8104         }
8105         return expandedTestSpec;
8106     }
8107 
add(char const * alias,char const * tag,SourceLineInfo const & lineInfo)8108     void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8109 
8110         if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
8111             std::ostringstream oss;
8112             oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
8113             throw std::domain_error( oss.str().c_str() );
8114         }
8115         if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
8116             std::ostringstream oss;
8117             oss << "error: tag alias, \"" << alias << "\" already registered.\n"
8118                 << "\tFirst seen at " << find(alias)->lineInfo << "\n"
8119                 << "\tRedefined at " << lineInfo;
8120             throw std::domain_error( oss.str().c_str() );
8121         }
8122     }
8123 
get()8124     TagAliasRegistry& TagAliasRegistry::get() {
8125         static TagAliasRegistry instance;
8126         return instance;
8127 
8128     }
8129 
~ITagAliasRegistry()8130     ITagAliasRegistry::~ITagAliasRegistry() {}
get()8131     ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
8132 
RegistrarForTagAliases(char const * alias,char const * tag,SourceLineInfo const & lineInfo)8133     RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8134         try {
8135             TagAliasRegistry::get().add( alias, tag, lineInfo );
8136         }
8137         catch( std::exception& ex ) {
8138             Colour colourGuard( Colour::Red );
8139             Catch::cerr() << ex.what() << std::endl;
8140             exit(1);
8141         }
8142     }
8143 
8144 } // end namespace Catch
8145 
8146 // #included from: ../reporters/catch_reporter_multi.hpp
8147 #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
8148 
8149 namespace Catch {
8150 
8151 class MultipleReporters : public SharedImpl<IStreamingReporter> {
8152     typedef std::vector<Ptr<IStreamingReporter> > Reporters;
8153     Reporters m_reporters;
8154 
8155 public:
add(Ptr<IStreamingReporter> const & reporter)8156     void add( Ptr<IStreamingReporter> const& reporter ) {
8157         m_reporters.push_back( reporter );
8158     }
8159 
8160 public: // IStreamingReporter
8161 
getPreferences() const8162     virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8163         return m_reporters[0]->getPreferences();
8164     }
8165 
noMatchingTestCases(std::string const & spec)8166     virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
8167         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8168                 it != itEnd;
8169                 ++it )
8170             (*it)->noMatchingTestCases( spec );
8171     }
8172 
testRunStarting(TestRunInfo const & testRunInfo)8173     virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
8174         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8175                 it != itEnd;
8176                 ++it )
8177             (*it)->testRunStarting( testRunInfo );
8178     }
8179 
testGroupStarting(GroupInfo const & groupInfo)8180     virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
8181         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8182                 it != itEnd;
8183                 ++it )
8184             (*it)->testGroupStarting( groupInfo );
8185     }
8186 
testCaseStarting(TestCaseInfo const & testInfo)8187     virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8188         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8189                 it != itEnd;
8190                 ++it )
8191             (*it)->testCaseStarting( testInfo );
8192     }
8193 
sectionStarting(SectionInfo const & sectionInfo)8194     virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8195         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8196                 it != itEnd;
8197                 ++it )
8198             (*it)->sectionStarting( sectionInfo );
8199     }
8200 
assertionStarting(AssertionInfo const & assertionInfo)8201     virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
8202         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8203                 it != itEnd;
8204                 ++it )
8205             (*it)->assertionStarting( assertionInfo );
8206     }
8207 
8208     // The return value indicates if the messages buffer should be cleared:
assertionEnded(AssertionStats const & assertionStats)8209     virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8210         bool clearBuffer = false;
8211         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8212                 it != itEnd;
8213                 ++it )
8214             clearBuffer |= (*it)->assertionEnded( assertionStats );
8215         return clearBuffer;
8216     }
8217 
sectionEnded(SectionStats const & sectionStats)8218     virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8219         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8220                 it != itEnd;
8221                 ++it )
8222             (*it)->sectionEnded( sectionStats );
8223     }
8224 
testCaseEnded(TestCaseStats const & testCaseStats)8225     virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8226         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8227                 it != itEnd;
8228                 ++it )
8229             (*it)->testCaseEnded( testCaseStats );
8230     }
8231 
testGroupEnded(TestGroupStats const & testGroupStats)8232     virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8233         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8234                 it != itEnd;
8235                 ++it )
8236             (*it)->testGroupEnded( testGroupStats );
8237     }
8238 
testRunEnded(TestRunStats const & testRunStats)8239     virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8240         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8241                 it != itEnd;
8242                 ++it )
8243             (*it)->testRunEnded( testRunStats );
8244     }
8245 
skipTest(TestCaseInfo const & testInfo)8246     virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8247         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8248                 it != itEnd;
8249                 ++it )
8250             (*it)->skipTest( testInfo );
8251     }
8252 };
8253 
addReporter(Ptr<IStreamingReporter> const & existingReporter,Ptr<IStreamingReporter> const & additionalReporter)8254 Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
8255     Ptr<IStreamingReporter> resultingReporter;
8256 
8257     if( existingReporter ) {
8258         MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
8259         if( !multi ) {
8260             multi = new MultipleReporters;
8261             resultingReporter = Ptr<IStreamingReporter>( multi );
8262             if( existingReporter )
8263                 multi->add( existingReporter );
8264         }
8265         else
8266             resultingReporter = existingReporter;
8267         multi->add( additionalReporter );
8268     }
8269     else
8270         resultingReporter = additionalReporter;
8271 
8272     return resultingReporter;
8273 }
8274 
8275 } // end namespace Catch
8276 
8277 // #included from: ../reporters/catch_reporter_xml.hpp
8278 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
8279 
8280 // #included from: catch_reporter_bases.hpp
8281 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
8282 
8283 #include <cstring>
8284 
8285 namespace Catch {
8286 
8287     struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
8288 
StreamingReporterBaseCatch::StreamingReporterBase8289         StreamingReporterBase( ReporterConfig const& _config )
8290         :   m_config( _config.fullConfig() ),
8291             stream( _config.stream() )
8292         {
8293             m_reporterPrefs.shouldRedirectStdOut = false;
8294         }
8295 
getPreferencesCatch::StreamingReporterBase8296         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8297             return m_reporterPrefs;
8298         }
8299 
8300         virtual ~StreamingReporterBase() CATCH_OVERRIDE;
8301 
noMatchingTestCasesCatch::StreamingReporterBase8302         virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
8303 
testRunStartingCatch::StreamingReporterBase8304         virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
8305             currentTestRunInfo = _testRunInfo;
8306         }
testGroupStartingCatch::StreamingReporterBase8307         virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
8308             currentGroupInfo = _groupInfo;
8309         }
8310 
testCaseStartingCatch::StreamingReporterBase8311         virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
8312             currentTestCaseInfo = _testInfo;
8313         }
sectionStartingCatch::StreamingReporterBase8314         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
8315             m_sectionStack.push_back( _sectionInfo );
8316         }
8317 
sectionEndedCatch::StreamingReporterBase8318         virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
8319             m_sectionStack.pop_back();
8320         }
testCaseEndedCatch::StreamingReporterBase8321         virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
8322             currentTestCaseInfo.reset();
8323         }
testGroupEndedCatch::StreamingReporterBase8324         virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
8325             currentGroupInfo.reset();
8326         }
testRunEndedCatch::StreamingReporterBase8327         virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
8328             currentTestCaseInfo.reset();
8329             currentGroupInfo.reset();
8330             currentTestRunInfo.reset();
8331         }
8332 
skipTestCatch::StreamingReporterBase8333         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
8334             // Don't do anything with this by default.
8335             // It can optionally be overridden in the derived class.
8336         }
8337 
8338         Ptr<IConfig const> m_config;
8339         std::ostream& stream;
8340 
8341         LazyStat<TestRunInfo> currentTestRunInfo;
8342         LazyStat<GroupInfo> currentGroupInfo;
8343         LazyStat<TestCaseInfo> currentTestCaseInfo;
8344 
8345         std::vector<SectionInfo> m_sectionStack;
8346         ReporterPreferences m_reporterPrefs;
8347     };
8348 
8349     struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
8350         template<typename T, typename ChildNodeT>
8351         struct Node : SharedImpl<> {
NodeCatch::CumulativeReporterBase::Node8352             explicit Node( T const& _value ) : value( _value ) {}
~NodeCatch::CumulativeReporterBase::Node8353             virtual ~Node() {}
8354 
8355             typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
8356             T value;
8357             ChildNodes children;
8358         };
8359         struct SectionNode : SharedImpl<> {
SectionNodeCatch::CumulativeReporterBase::SectionNode8360             explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
8361             virtual ~SectionNode();
8362 
operator ==Catch::CumulativeReporterBase::SectionNode8363             bool operator == ( SectionNode const& other ) const {
8364                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
8365             }
operator ==Catch::CumulativeReporterBase::SectionNode8366             bool operator == ( Ptr<SectionNode> const& other ) const {
8367                 return operator==( *other );
8368             }
8369 
8370             SectionStats stats;
8371             typedef std::vector<Ptr<SectionNode> > ChildSections;
8372             typedef std::vector<AssertionStats> Assertions;
8373             ChildSections childSections;
8374             Assertions assertions;
8375             std::string stdOut;
8376             std::string stdErr;
8377         };
8378 
8379         struct BySectionInfo {
BySectionInfoCatch::CumulativeReporterBase::BySectionInfo8380             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
BySectionInfoCatch::CumulativeReporterBase::BySectionInfo8381 			BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
operator ()Catch::CumulativeReporterBase::BySectionInfo8382             bool operator() ( Ptr<SectionNode> const& node ) const {
8383                 return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
8384             }
8385         private:
8386 			void operator=( BySectionInfo const& );
8387             SectionInfo const& m_other;
8388         };
8389 
8390         typedef Node<TestCaseStats, SectionNode> TestCaseNode;
8391         typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
8392         typedef Node<TestRunStats, TestGroupNode> TestRunNode;
8393 
CumulativeReporterBaseCatch::CumulativeReporterBase8394         CumulativeReporterBase( ReporterConfig const& _config )
8395         :   m_config( _config.fullConfig() ),
8396             stream( _config.stream() )
8397         {
8398             m_reporterPrefs.shouldRedirectStdOut = false;
8399         }
8400         ~CumulativeReporterBase();
8401 
getPreferencesCatch::CumulativeReporterBase8402         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8403             return m_reporterPrefs;
8404         }
8405 
testRunStartingCatch::CumulativeReporterBase8406         virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
testGroupStartingCatch::CumulativeReporterBase8407         virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
8408 
testCaseStartingCatch::CumulativeReporterBase8409         virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
8410 
sectionStartingCatch::CumulativeReporterBase8411         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8412             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
8413             Ptr<SectionNode> node;
8414             if( m_sectionStack.empty() ) {
8415                 if( !m_rootSection )
8416                     m_rootSection = new SectionNode( incompleteStats );
8417                 node = m_rootSection;
8418             }
8419             else {
8420                 SectionNode& parentNode = *m_sectionStack.back();
8421                 SectionNode::ChildSections::const_iterator it =
8422                     std::find_if(   parentNode.childSections.begin(),
8423                                     parentNode.childSections.end(),
8424                                     BySectionInfo( sectionInfo ) );
8425                 if( it == parentNode.childSections.end() ) {
8426                     node = new SectionNode( incompleteStats );
8427                     parentNode.childSections.push_back( node );
8428                 }
8429                 else
8430                     node = *it;
8431             }
8432             m_sectionStack.push_back( node );
8433             m_deepestSection = node;
8434         }
8435 
assertionStartingCatch::CumulativeReporterBase8436         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
8437 
assertionEndedCatch::CumulativeReporterBase8438         virtual bool assertionEnded( AssertionStats const& assertionStats ) {
8439             assert( !m_sectionStack.empty() );
8440             SectionNode& sectionNode = *m_sectionStack.back();
8441             sectionNode.assertions.push_back( assertionStats );
8442             return true;
8443         }
sectionEndedCatch::CumulativeReporterBase8444         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8445             assert( !m_sectionStack.empty() );
8446             SectionNode& node = *m_sectionStack.back();
8447             node.stats = sectionStats;
8448             m_sectionStack.pop_back();
8449         }
testCaseEndedCatch::CumulativeReporterBase8450         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8451             Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
8452             assert( m_sectionStack.size() == 0 );
8453             node->children.push_back( m_rootSection );
8454             m_testCases.push_back( node );
8455             m_rootSection.reset();
8456 
8457             assert( m_deepestSection );
8458             m_deepestSection->stdOut = testCaseStats.stdOut;
8459             m_deepestSection->stdErr = testCaseStats.stdErr;
8460         }
testGroupEndedCatch::CumulativeReporterBase8461         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8462             Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
8463             node->children.swap( m_testCases );
8464             m_testGroups.push_back( node );
8465         }
testRunEndedCatch::CumulativeReporterBase8466         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8467             Ptr<TestRunNode> node = new TestRunNode( testRunStats );
8468             node->children.swap( m_testGroups );
8469             m_testRuns.push_back( node );
8470             testRunEndedCumulative();
8471         }
8472         virtual void testRunEndedCumulative() = 0;
8473 
skipTestCatch::CumulativeReporterBase8474         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
8475 
8476         Ptr<IConfig const> m_config;
8477         std::ostream& stream;
8478         std::vector<AssertionStats> m_assertions;
8479         std::vector<std::vector<Ptr<SectionNode> > > m_sections;
8480         std::vector<Ptr<TestCaseNode> > m_testCases;
8481         std::vector<Ptr<TestGroupNode> > m_testGroups;
8482 
8483         std::vector<Ptr<TestRunNode> > m_testRuns;
8484 
8485         Ptr<SectionNode> m_rootSection;
8486         Ptr<SectionNode> m_deepestSection;
8487         std::vector<Ptr<SectionNode> > m_sectionStack;
8488         ReporterPreferences m_reporterPrefs;
8489 
8490     };
8491 
8492     template<char C>
getLineOfChars()8493     char const* getLineOfChars() {
8494         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
8495         if( !*line ) {
8496             memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
8497             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
8498         }
8499         return line;
8500     }
8501 
8502     struct TestEventListenerBase : StreamingReporterBase {
TestEventListenerBaseCatch::TestEventListenerBase8503         TestEventListenerBase( ReporterConfig const& _config )
8504         :   StreamingReporterBase( _config )
8505         {}
8506 
assertionStartingCatch::TestEventListenerBase8507         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
assertionEndedCatch::TestEventListenerBase8508         virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
8509             return false;
8510         }
8511     };
8512 
8513 } // end namespace Catch
8514 
8515 // #included from: ../internal/catch_reporter_registrars.hpp
8516 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
8517 
8518 namespace Catch {
8519 
8520     template<typename T>
8521     class LegacyReporterRegistrar {
8522 
8523         class ReporterFactory : public IReporterFactory {
create(ReporterConfig const & config) const8524             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8525                 return new LegacyReporterAdapter( new T( config ) );
8526             }
8527 
getDescription() const8528             virtual std::string getDescription() const {
8529                 return T::getDescription();
8530             }
8531         };
8532 
8533     public:
8534 
LegacyReporterRegistrar(std::string const & name)8535         LegacyReporterRegistrar( std::string const& name ) {
8536             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8537         }
8538     };
8539 
8540     template<typename T>
8541     class ReporterRegistrar {
8542 
8543         class ReporterFactory : public SharedImpl<IReporterFactory> {
8544 
8545             // *** Please Note ***:
8546             // - If you end up here looking at a compiler error because it's trying to register
8547             // your custom reporter class be aware that the native reporter interface has changed
8548             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
8549             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
8550             // However please consider updating to the new interface as the old one is now
8551             // deprecated and will probably be removed quite soon!
8552             // Please contact me via github if you have any questions at all about this.
8553             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
8554             // no idea who is actually using custom reporters at all (possibly no-one!).
8555             // The new interface is designed to minimise exposure to interface changes in the future.
create(ReporterConfig const & config) const8556             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8557                 return new T( config );
8558             }
8559 
getDescription() const8560             virtual std::string getDescription() const {
8561                 return T::getDescription();
8562             }
8563         };
8564 
8565     public:
8566 
ReporterRegistrar(std::string const & name)8567         ReporterRegistrar( std::string const& name ) {
8568             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8569         }
8570     };
8571 
8572     template<typename T>
8573     class ListenerRegistrar {
8574 
8575         class ListenerFactory : public SharedImpl<IReporterFactory> {
8576 
create(ReporterConfig const & config) const8577             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8578                 return new T( config );
8579             }
getDescription() const8580             virtual std::string getDescription() const {
8581                 return "";
8582             }
8583         };
8584 
8585     public:
8586 
ListenerRegistrar()8587         ListenerRegistrar() {
8588             getMutableRegistryHub().registerListener( new ListenerFactory() );
8589         }
8590     };
8591 }
8592 
8593 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
8594     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
8595 
8596 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
8597     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
8598 
8599 #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
8600     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
8601 
8602 // #included from: ../internal/catch_xmlwriter.hpp
8603 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
8604 
8605 #include <sstream>
8606 #include <string>
8607 #include <vector>
8608 #include <iomanip>
8609 
8610 namespace Catch {
8611 
8612     class XmlEncode {
8613     public:
8614         enum ForWhat { ForTextNodes, ForAttributes };
8615 
XmlEncode(std::string const & str,ForWhat forWhat=ForTextNodes)8616         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
8617         :   m_str( str ),
8618             m_forWhat( forWhat )
8619         {}
8620 
encodeTo(std::ostream & os) const8621         void encodeTo( std::ostream& os ) const {
8622 
8623             // Apostrophe escaping not necessary if we always use " to write attributes
8624             // (see: http://www.w3.org/TR/xml/#syntax)
8625 
8626             for( std::size_t i = 0; i < m_str.size(); ++ i ) {
8627                 char c = m_str[i];
8628                 switch( c ) {
8629                     case '<':   os << "&lt;"; break;
8630                     case '&':   os << "&amp;"; break;
8631 
8632                     case '>':
8633                         // See: http://www.w3.org/TR/xml/#syntax
8634                         if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
8635                             os << "&gt;";
8636                         else
8637                             os << c;
8638                         break;
8639 
8640                     case '\"':
8641                         if( m_forWhat == ForAttributes )
8642                             os << "&quot;";
8643                         else
8644                             os << c;
8645                         break;
8646 
8647                     default:
8648                         // Escape control chars - based on contribution by @espenalb in PR #465
8649                         if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
8650                             os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
8651                         else
8652                             os << c;
8653                 }
8654             }
8655         }
8656 
operator <<(std::ostream & os,XmlEncode const & xmlEncode)8657         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
8658             xmlEncode.encodeTo( os );
8659             return os;
8660         }
8661 
8662     private:
8663         std::string m_str;
8664         ForWhat m_forWhat;
8665     };
8666 
8667     class XmlWriter {
8668     public:
8669 
8670         class ScopedElement {
8671         public:
ScopedElement(XmlWriter * writer)8672             ScopedElement( XmlWriter* writer )
8673             :   m_writer( writer )
8674             {}
8675 
ScopedElement(ScopedElement const & other)8676             ScopedElement( ScopedElement const& other )
8677             :   m_writer( other.m_writer ){
8678                 other.m_writer = CATCH_NULL;
8679             }
8680 
~ScopedElement()8681             ~ScopedElement() {
8682                 if( m_writer )
8683                     m_writer->endElement();
8684             }
8685 
writeText(std::string const & text,bool indent=true)8686             ScopedElement& writeText( std::string const& text, bool indent = true ) {
8687                 m_writer->writeText( text, indent );
8688                 return *this;
8689             }
8690 
8691             template<typename T>
writeAttribute(std::string const & name,T const & attribute)8692             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
8693                 m_writer->writeAttribute( name, attribute );
8694                 return *this;
8695             }
8696 
8697         private:
8698             mutable XmlWriter* m_writer;
8699         };
8700 
XmlWriter()8701         XmlWriter()
8702         :   m_tagIsOpen( false ),
8703             m_needsNewline( false ),
8704             m_os( &Catch::cout() )
8705         {}
8706 
XmlWriter(std::ostream & os)8707         XmlWriter( std::ostream& os )
8708         :   m_tagIsOpen( false ),
8709             m_needsNewline( false ),
8710             m_os( &os )
8711         {}
8712 
~XmlWriter()8713         ~XmlWriter() {
8714             while( !m_tags.empty() )
8715                 endElement();
8716         }
8717 
startElement(std::string const & name)8718         XmlWriter& startElement( std::string const& name ) {
8719             ensureTagClosed();
8720             newlineIfNecessary();
8721             stream() << m_indent << "<" << name;
8722             m_tags.push_back( name );
8723             m_indent += "  ";
8724             m_tagIsOpen = true;
8725             return *this;
8726         }
8727 
scopedElement(std::string const & name)8728         ScopedElement scopedElement( std::string const& name ) {
8729             ScopedElement scoped( this );
8730             startElement( name );
8731             return scoped;
8732         }
8733 
endElement()8734         XmlWriter& endElement() {
8735             newlineIfNecessary();
8736             m_indent = m_indent.substr( 0, m_indent.size()-2 );
8737             if( m_tagIsOpen ) {
8738                 stream() << "/>\n";
8739                 m_tagIsOpen = false;
8740             }
8741             else {
8742                 stream() << m_indent << "</" << m_tags.back() << ">\n";
8743             }
8744             m_tags.pop_back();
8745             return *this;
8746         }
8747 
writeAttribute(std::string const & name,std::string const & attribute)8748         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
8749             if( !name.empty() && !attribute.empty() )
8750                 stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
8751             return *this;
8752         }
8753 
writeAttribute(std::string const & name,bool attribute)8754         XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
8755             stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
8756             return *this;
8757         }
8758 
8759         template<typename T>
writeAttribute(std::string const & name,T const & attribute)8760         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
8761             std::ostringstream oss;
8762             oss << attribute;
8763             return writeAttribute( name, oss.str() );
8764         }
8765 
writeText(std::string const & text,bool indent=true)8766         XmlWriter& writeText( std::string const& text, bool indent = true ) {
8767             if( !text.empty() ){
8768                 bool tagWasOpen = m_tagIsOpen;
8769                 ensureTagClosed();
8770                 if( tagWasOpen && indent )
8771                     stream() << m_indent;
8772                 stream() << XmlEncode( text );
8773                 m_needsNewline = true;
8774             }
8775             return *this;
8776         }
8777 
writeComment(std::string const & text)8778         XmlWriter& writeComment( std::string const& text ) {
8779             ensureTagClosed();
8780             stream() << m_indent << "<!--" << text << "-->";
8781             m_needsNewline = true;
8782             return *this;
8783         }
8784 
writeBlankLine()8785         XmlWriter& writeBlankLine() {
8786             ensureTagClosed();
8787             stream() << "\n";
8788             return *this;
8789         }
8790 
setStream(std::ostream & os)8791         void setStream( std::ostream& os ) {
8792             m_os = &os;
8793         }
8794 
8795     private:
8796         XmlWriter( XmlWriter const& );
8797         void operator=( XmlWriter const& );
8798 
stream()8799         std::ostream& stream() {
8800             return *m_os;
8801         }
8802 
ensureTagClosed()8803         void ensureTagClosed() {
8804             if( m_tagIsOpen ) {
8805                 stream() << ">\n";
8806                 m_tagIsOpen = false;
8807             }
8808         }
8809 
newlineIfNecessary()8810         void newlineIfNecessary() {
8811             if( m_needsNewline ) {
8812                 stream() << "\n";
8813                 m_needsNewline = false;
8814             }
8815         }
8816 
8817         bool m_tagIsOpen;
8818         bool m_needsNewline;
8819         std::vector<std::string> m_tags;
8820         std::string m_indent;
8821         std::ostream* m_os;
8822     };
8823 
8824 }
8825 // #included from: catch_reenable_warnings.h
8826 
8827 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
8828 
8829 #ifdef __clang__
8830 #    ifdef __ICC // icpc defines the __clang__ macro
8831 #        pragma warning(pop)
8832 #    else
8833 #        pragma clang diagnostic pop
8834 #    endif
8835 #elif defined __GNUC__
8836 #    pragma GCC diagnostic pop
8837 #endif
8838 
8839 
8840 namespace Catch {
8841     class XmlReporter : public StreamingReporterBase {
8842     public:
XmlReporter(ReporterConfig const & _config)8843         XmlReporter( ReporterConfig const& _config )
8844         :   StreamingReporterBase( _config ),
8845             m_sectionDepth( 0 )
8846         {
8847             m_reporterPrefs.shouldRedirectStdOut = true;
8848         }
8849 
8850         virtual ~XmlReporter() CATCH_OVERRIDE;
8851 
getDescription()8852         static std::string getDescription() {
8853             return "Reports test results as an XML document";
8854         }
8855 
8856     public: // StreamingReporterBase
8857 
noMatchingTestCases(std::string const & s)8858         virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
8859             StreamingReporterBase::noMatchingTestCases( s );
8860         }
8861 
testRunStarting(TestRunInfo const & testInfo)8862         virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
8863             StreamingReporterBase::testRunStarting( testInfo );
8864             m_xml.setStream( stream );
8865             m_xml.startElement( "Catch" );
8866             if( !m_config->name().empty() )
8867                 m_xml.writeAttribute( "name", m_config->name() );
8868         }
8869 
testGroupStarting(GroupInfo const & groupInfo)8870         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
8871             StreamingReporterBase::testGroupStarting( groupInfo );
8872             m_xml.startElement( "Group" )
8873                 .writeAttribute( "name", groupInfo.name );
8874         }
8875 
testCaseStarting(TestCaseInfo const & testInfo)8876         virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8877             StreamingReporterBase::testCaseStarting(testInfo);
8878             m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
8879 
8880             if ( m_config->showDurations() == ShowDurations::Always )
8881                 m_testCaseTimer.start();
8882         }
8883 
sectionStarting(SectionInfo const & sectionInfo)8884         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8885             StreamingReporterBase::sectionStarting( sectionInfo );
8886             if( m_sectionDepth++ > 0 ) {
8887                 m_xml.startElement( "Section" )
8888                     .writeAttribute( "name", trim( sectionInfo.name ) )
8889                     .writeAttribute( "description", sectionInfo.description );
8890             }
8891         }
8892 
assertionStarting(AssertionInfo const &)8893         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
8894 
assertionEnded(AssertionStats const & assertionStats)8895         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8896             const AssertionResult& assertionResult = assertionStats.assertionResult;
8897 
8898             // Print any info messages in <Info> tags.
8899             if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
8900                 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
8901                         it != itEnd;
8902                         ++it ) {
8903                     if( it->type == ResultWas::Info ) {
8904                         m_xml.scopedElement( "Info" )
8905                             .writeText( it->message );
8906                     } else if ( it->type == ResultWas::Warning ) {
8907                         m_xml.scopedElement( "Warning" )
8908                             .writeText( it->message );
8909                     }
8910                 }
8911             }
8912 
8913             // Drop out if result was successful but we're not printing them.
8914             if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
8915                 return true;
8916 
8917             // Print the expression if there is one.
8918             if( assertionResult.hasExpression() ) {
8919                 m_xml.startElement( "Expression" )
8920                     .writeAttribute( "success", assertionResult.succeeded() )
8921 					.writeAttribute( "type", assertionResult.getTestMacroName() )
8922                     .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8923                     .writeAttribute( "line", assertionResult.getSourceInfo().line );
8924 
8925                 m_xml.scopedElement( "Original" )
8926                     .writeText( assertionResult.getExpression() );
8927                 m_xml.scopedElement( "Expanded" )
8928                     .writeText( assertionResult.getExpandedExpression() );
8929             }
8930 
8931             // And... Print a result applicable to each result type.
8932             switch( assertionResult.getResultType() ) {
8933                 case ResultWas::ThrewException:
8934                     m_xml.scopedElement( "Exception" )
8935                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8936                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
8937                         .writeText( assertionResult.getMessage() );
8938                     break;
8939                 case ResultWas::FatalErrorCondition:
8940                     m_xml.scopedElement( "Fatal Error Condition" )
8941                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8942                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
8943                         .writeText( assertionResult.getMessage() );
8944                     break;
8945                 case ResultWas::Info:
8946                     m_xml.scopedElement( "Info" )
8947                         .writeText( assertionResult.getMessage() );
8948                     break;
8949                 case ResultWas::Warning:
8950                     // Warning will already have been written
8951                     break;
8952                 case ResultWas::ExplicitFailure:
8953                     m_xml.scopedElement( "Failure" )
8954                         .writeText( assertionResult.getMessage() );
8955                     break;
8956                 default:
8957                     break;
8958             }
8959 
8960             if( assertionResult.hasExpression() )
8961                 m_xml.endElement();
8962 
8963             return true;
8964         }
8965 
sectionEnded(SectionStats const & sectionStats)8966         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8967             StreamingReporterBase::sectionEnded( sectionStats );
8968             if( --m_sectionDepth > 0 ) {
8969                 XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
8970                 e.writeAttribute( "successes", sectionStats.assertions.passed );
8971                 e.writeAttribute( "failures", sectionStats.assertions.failed );
8972                 e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
8973 
8974                 if ( m_config->showDurations() == ShowDurations::Always )
8975                     e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
8976 
8977                 m_xml.endElement();
8978             }
8979         }
8980 
testCaseEnded(TestCaseStats const & testCaseStats)8981         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8982             StreamingReporterBase::testCaseEnded( testCaseStats );
8983             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
8984             e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
8985 
8986             if ( m_config->showDurations() == ShowDurations::Always )
8987                 e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
8988 
8989             m_xml.endElement();
8990         }
8991 
testGroupEnded(TestGroupStats const & testGroupStats)8992         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8993             StreamingReporterBase::testGroupEnded( testGroupStats );
8994             // TODO: Check testGroupStats.aborting and act accordingly.
8995             m_xml.scopedElement( "OverallResults" )
8996                 .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
8997                 .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
8998                 .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
8999             m_xml.endElement();
9000         }
9001 
testRunEnded(TestRunStats const & testRunStats)9002         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
9003             StreamingReporterBase::testRunEnded( testRunStats );
9004             m_xml.scopedElement( "OverallResults" )
9005                 .writeAttribute( "successes", testRunStats.totals.assertions.passed )
9006                 .writeAttribute( "failures", testRunStats.totals.assertions.failed )
9007                 .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
9008             m_xml.endElement();
9009         }
9010 
9011     private:
9012         Timer m_testCaseTimer;
9013         XmlWriter m_xml;
9014         int m_sectionDepth;
9015     };
9016 
9017      INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
9018 
9019 } // end namespace Catch
9020 
9021 // #included from: ../reporters/catch_reporter_junit.hpp
9022 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
9023 
9024 #include <assert.h>
9025 
9026 namespace Catch {
9027 
9028     class JunitReporter : public CumulativeReporterBase {
9029     public:
JunitReporter(ReporterConfig const & _config)9030         JunitReporter( ReporterConfig const& _config )
9031         :   CumulativeReporterBase( _config ),
9032             xml( _config.stream() )
9033         {
9034             m_reporterPrefs.shouldRedirectStdOut = true;
9035         }
9036 
9037         virtual ~JunitReporter() CATCH_OVERRIDE;
9038 
getDescription()9039         static std::string getDescription() {
9040             return "Reports test results in an XML format that looks like Ant's junitreport target";
9041         }
9042 
noMatchingTestCases(std::string const &)9043         virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
9044 
testRunStarting(TestRunInfo const & runInfo)9045         virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
9046             CumulativeReporterBase::testRunStarting( runInfo );
9047             xml.startElement( "testsuites" );
9048         }
9049 
testGroupStarting(GroupInfo const & groupInfo)9050         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9051             suiteTimer.start();
9052             stdOutForSuite.str("");
9053             stdErrForSuite.str("");
9054             unexpectedExceptions = 0;
9055             CumulativeReporterBase::testGroupStarting( groupInfo );
9056         }
9057 
assertionEnded(AssertionStats const & assertionStats)9058         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9059             if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
9060                 unexpectedExceptions++;
9061             return CumulativeReporterBase::assertionEnded( assertionStats );
9062         }
9063 
testCaseEnded(TestCaseStats const & testCaseStats)9064         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9065             stdOutForSuite << testCaseStats.stdOut;
9066             stdErrForSuite << testCaseStats.stdErr;
9067             CumulativeReporterBase::testCaseEnded( testCaseStats );
9068         }
9069 
testGroupEnded(TestGroupStats const & testGroupStats)9070         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9071             double suiteTime = suiteTimer.getElapsedSeconds();
9072             CumulativeReporterBase::testGroupEnded( testGroupStats );
9073             writeGroup( *m_testGroups.back(), suiteTime );
9074         }
9075 
testRunEndedCumulative()9076         virtual void testRunEndedCumulative() CATCH_OVERRIDE {
9077             xml.endElement();
9078         }
9079 
writeGroup(TestGroupNode const & groupNode,double suiteTime)9080         void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
9081             XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
9082             TestGroupStats const& stats = groupNode.value;
9083             xml.writeAttribute( "name", stats.groupInfo.name );
9084             xml.writeAttribute( "errors", unexpectedExceptions );
9085             xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
9086             xml.writeAttribute( "tests", stats.totals.assertions.total() );
9087             xml.writeAttribute( "hostname", "tbd" ); // !TBD
9088             if( m_config->showDurations() == ShowDurations::Never )
9089                 xml.writeAttribute( "time", "" );
9090             else
9091                 xml.writeAttribute( "time", suiteTime );
9092             xml.writeAttribute( "timestamp", "tbd" ); // !TBD
9093 
9094             // Write test cases
9095             for( TestGroupNode::ChildNodes::const_iterator
9096                     it = groupNode.children.begin(), itEnd = groupNode.children.end();
9097                     it != itEnd;
9098                     ++it )
9099                 writeTestCase( **it );
9100 
9101             xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
9102             xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
9103         }
9104 
writeTestCase(TestCaseNode const & testCaseNode)9105         void writeTestCase( TestCaseNode const& testCaseNode ) {
9106             TestCaseStats const& stats = testCaseNode.value;
9107 
9108             // All test cases have exactly one section - which represents the
9109             // test case itself. That section may have 0-n nested sections
9110             assert( testCaseNode.children.size() == 1 );
9111             SectionNode const& rootSection = *testCaseNode.children.front();
9112 
9113             std::string className = stats.testInfo.className;
9114 
9115             if( className.empty() ) {
9116                 if( rootSection.childSections.empty() )
9117                     className = "global";
9118             }
9119             writeSection( className, "", rootSection );
9120         }
9121 
writeSection(std::string const & className,std::string const & rootName,SectionNode const & sectionNode)9122         void writeSection(  std::string const& className,
9123                             std::string const& rootName,
9124                             SectionNode const& sectionNode ) {
9125             std::string name = trim( sectionNode.stats.sectionInfo.name );
9126             if( !rootName.empty() )
9127                 name = rootName + "/" + name;
9128 
9129             if( !sectionNode.assertions.empty() ||
9130                 !sectionNode.stdOut.empty() ||
9131                 !sectionNode.stdErr.empty() ) {
9132                 XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
9133                 if( className.empty() ) {
9134                     xml.writeAttribute( "classname", name );
9135                     xml.writeAttribute( "name", "root" );
9136                 }
9137                 else {
9138                     xml.writeAttribute( "classname", className );
9139                     xml.writeAttribute( "name", name );
9140                 }
9141                 xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
9142 
9143                 writeAssertions( sectionNode );
9144 
9145                 if( !sectionNode.stdOut.empty() )
9146                     xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
9147                 if( !sectionNode.stdErr.empty() )
9148                     xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
9149             }
9150             for( SectionNode::ChildSections::const_iterator
9151                     it = sectionNode.childSections.begin(),
9152                     itEnd = sectionNode.childSections.end();
9153                     it != itEnd;
9154                     ++it )
9155                 if( className.empty() )
9156                     writeSection( name, "", **it );
9157                 else
9158                     writeSection( className, name, **it );
9159         }
9160 
writeAssertions(SectionNode const & sectionNode)9161         void writeAssertions( SectionNode const& sectionNode ) {
9162             for( SectionNode::Assertions::const_iterator
9163                     it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
9164                     it != itEnd;
9165                     ++it )
9166                 writeAssertion( *it );
9167         }
writeAssertion(AssertionStats const & stats)9168         void writeAssertion( AssertionStats const& stats ) {
9169             AssertionResult const& result = stats.assertionResult;
9170             if( !result.isOk() ) {
9171                 std::string elementName;
9172                 switch( result.getResultType() ) {
9173                     case ResultWas::ThrewException:
9174                     case ResultWas::FatalErrorCondition:
9175                         elementName = "error";
9176                         break;
9177                     case ResultWas::ExplicitFailure:
9178                         elementName = "failure";
9179                         break;
9180                     case ResultWas::ExpressionFailed:
9181                         elementName = "failure";
9182                         break;
9183                     case ResultWas::DidntThrowException:
9184                         elementName = "failure";
9185                         break;
9186 
9187                     // We should never see these here:
9188                     case ResultWas::Info:
9189                     case ResultWas::Warning:
9190                     case ResultWas::Ok:
9191                     case ResultWas::Unknown:
9192                     case ResultWas::FailureBit:
9193                     case ResultWas::Exception:
9194                         elementName = "internalError";
9195                         break;
9196                 }
9197 
9198                 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
9199 
9200                 xml.writeAttribute( "message", result.getExpandedExpression() );
9201                 xml.writeAttribute( "type", result.getTestMacroName() );
9202 
9203                 std::ostringstream oss;
9204                 if( !result.getMessage().empty() )
9205                     oss << result.getMessage() << "\n";
9206                 for( std::vector<MessageInfo>::const_iterator
9207                         it = stats.infoMessages.begin(),
9208                         itEnd = stats.infoMessages.end();
9209                             it != itEnd;
9210                             ++it )
9211                     if( it->type == ResultWas::Info )
9212                         oss << it->message << "\n";
9213 
9214                 oss << "at " << result.getSourceInfo();
9215                 xml.writeText( oss.str(), false );
9216             }
9217         }
9218 
9219         XmlWriter xml;
9220         Timer suiteTimer;
9221         std::ostringstream stdOutForSuite;
9222         std::ostringstream stdErrForSuite;
9223         unsigned int unexpectedExceptions;
9224     };
9225 
9226     INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
9227 
9228 } // end namespace Catch
9229 
9230 // #included from: ../reporters/catch_reporter_console.hpp
9231 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
9232 
9233 namespace Catch {
9234 
9235     struct ConsoleReporter : StreamingReporterBase {
ConsoleReporterCatch::ConsoleReporter9236         ConsoleReporter( ReporterConfig const& _config )
9237         :   StreamingReporterBase( _config ),
9238             m_headerPrinted( false )
9239         {}
9240 
9241         virtual ~ConsoleReporter() CATCH_OVERRIDE;
getDescriptionCatch::ConsoleReporter9242         static std::string getDescription() {
9243             return "Reports test results as plain lines of text";
9244         }
9245 
noMatchingTestCasesCatch::ConsoleReporter9246         virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
9247             stream << "No test cases matched '" << spec << "'" << std::endl;
9248         }
9249 
assertionStartingCatch::ConsoleReporter9250         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
9251         }
9252 
assertionEndedCatch::ConsoleReporter9253         virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
9254             AssertionResult const& result = _assertionStats.assertionResult;
9255 
9256             bool printInfoMessages = true;
9257 
9258             // Drop out if result was successful and we're not printing those
9259             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9260                 if( result.getResultType() != ResultWas::Warning )
9261                     return false;
9262                 printInfoMessages = false;
9263             }
9264 
9265             lazyPrint();
9266 
9267             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9268             printer.print();
9269             stream << std::endl;
9270             return true;
9271         }
9272 
sectionStartingCatch::ConsoleReporter9273         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
9274             m_headerPrinted = false;
9275             StreamingReporterBase::sectionStarting( _sectionInfo );
9276         }
sectionEndedCatch::ConsoleReporter9277         virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
9278             if( _sectionStats.missingAssertions ) {
9279                 lazyPrint();
9280                 Colour colour( Colour::ResultError );
9281                 if( m_sectionStack.size() > 1 )
9282                     stream << "\nNo assertions in section";
9283                 else
9284                     stream << "\nNo assertions in test case";
9285                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
9286             }
9287             if( m_headerPrinted ) {
9288                 if( m_config->showDurations() == ShowDurations::Always )
9289                     stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9290                 m_headerPrinted = false;
9291             }
9292             else {
9293                 if( m_config->showDurations() == ShowDurations::Always )
9294                     stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9295             }
9296             StreamingReporterBase::sectionEnded( _sectionStats );
9297         }
9298 
testCaseEndedCatch::ConsoleReporter9299         virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
9300             StreamingReporterBase::testCaseEnded( _testCaseStats );
9301             m_headerPrinted = false;
9302         }
testGroupEndedCatch::ConsoleReporter9303         virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
9304             if( currentGroupInfo.used ) {
9305                 printSummaryDivider();
9306                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
9307                 printTotals( _testGroupStats.totals );
9308                 stream << "\n" << std::endl;
9309             }
9310             StreamingReporterBase::testGroupEnded( _testGroupStats );
9311         }
testRunEndedCatch::ConsoleReporter9312         virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
9313             printTotalsDivider( _testRunStats.totals );
9314             printTotals( _testRunStats.totals );
9315             stream << std::endl;
9316             StreamingReporterBase::testRunEnded( _testRunStats );
9317         }
9318 
9319     private:
9320 
9321         class AssertionPrinter {
9322             void operator= ( AssertionPrinter const& );
9323         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)9324             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
9325             :   stream( _stream ),
9326                 stats( _stats ),
9327                 result( _stats.assertionResult ),
9328                 colour( Colour::None ),
9329                 message( result.getMessage() ),
9330                 messages( _stats.infoMessages ),
9331                 printInfoMessages( _printInfoMessages )
9332             {
9333                 switch( result.getResultType() ) {
9334                     case ResultWas::Ok:
9335                         colour = Colour::Success;
9336                         passOrFail = "PASSED";
9337                         //if( result.hasMessage() )
9338                         if( _stats.infoMessages.size() == 1 )
9339                             messageLabel = "with message";
9340                         if( _stats.infoMessages.size() > 1 )
9341                             messageLabel = "with messages";
9342                         break;
9343                     case ResultWas::ExpressionFailed:
9344                         if( result.isOk() ) {
9345                             colour = Colour::Success;
9346                             passOrFail = "FAILED - but was ok";
9347                         }
9348                         else {
9349                             colour = Colour::Error;
9350                             passOrFail = "FAILED";
9351                         }
9352                         if( _stats.infoMessages.size() == 1 )
9353                             messageLabel = "with message";
9354                         if( _stats.infoMessages.size() > 1 )
9355                             messageLabel = "with messages";
9356                         break;
9357                     case ResultWas::ThrewException:
9358                         colour = Colour::Error;
9359                         passOrFail = "FAILED";
9360                         messageLabel = "due to unexpected exception with message";
9361                         break;
9362                     case ResultWas::FatalErrorCondition:
9363                         colour = Colour::Error;
9364                         passOrFail = "FAILED";
9365                         messageLabel = "due to a fatal error condition";
9366                         break;
9367                     case ResultWas::DidntThrowException:
9368                         colour = Colour::Error;
9369                         passOrFail = "FAILED";
9370                         messageLabel = "because no exception was thrown where one was expected";
9371                         break;
9372                     case ResultWas::Info:
9373                         messageLabel = "info";
9374                         break;
9375                     case ResultWas::Warning:
9376                         messageLabel = "warning";
9377                         break;
9378                     case ResultWas::ExplicitFailure:
9379                         passOrFail = "FAILED";
9380                         colour = Colour::Error;
9381                         if( _stats.infoMessages.size() == 1 )
9382                             messageLabel = "explicitly with message";
9383                         if( _stats.infoMessages.size() > 1 )
9384                             messageLabel = "explicitly with messages";
9385                         break;
9386                     // These cases are here to prevent compiler warnings
9387                     case ResultWas::Unknown:
9388                     case ResultWas::FailureBit:
9389                     case ResultWas::Exception:
9390                         passOrFail = "** internal error **";
9391                         colour = Colour::Error;
9392                         break;
9393                 }
9394             }
9395 
print() const9396             void print() const {
9397                 printSourceInfo();
9398                 if( stats.totals.assertions.total() > 0 ) {
9399                     if( result.isOk() )
9400                         stream << "\n";
9401                     printResultType();
9402                     printOriginalExpression();
9403                     printReconstructedExpression();
9404                 }
9405                 else {
9406                     stream << "\n";
9407                 }
9408                 printMessage();
9409             }
9410 
9411         private:
printResultType() const9412             void printResultType() const {
9413                 if( !passOrFail.empty() ) {
9414                     Colour colourGuard( colour );
9415                     stream << passOrFail << ":\n";
9416                 }
9417             }
printOriginalExpression() const9418             void printOriginalExpression() const {
9419                 if( result.hasExpression() ) {
9420                     Colour colourGuard( Colour::OriginalExpression );
9421                     stream  << "  ";
9422                     stream << result.getExpressionInMacro();
9423                     stream << "\n";
9424                 }
9425             }
printReconstructedExpression() const9426             void printReconstructedExpression() const {
9427                 if( result.hasExpandedExpression() ) {
9428                     stream << "with expansion:\n";
9429                     Colour colourGuard( Colour::ReconstructedExpression );
9430                     stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
9431                 }
9432             }
printMessage() const9433             void printMessage() const {
9434                 if( !messageLabel.empty() )
9435                     stream << messageLabel << ":" << "\n";
9436                 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
9437                         it != itEnd;
9438                         ++it ) {
9439                     // If this assertion is a warning ignore any INFO messages
9440                     if( printInfoMessages || it->type != ResultWas::Info )
9441                         stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
9442                 }
9443             }
printSourceInfo() const9444             void printSourceInfo() const {
9445                 Colour colourGuard( Colour::FileName );
9446                 stream << result.getSourceInfo() << ": ";
9447             }
9448 
9449             std::ostream& stream;
9450             AssertionStats const& stats;
9451             AssertionResult const& result;
9452             Colour::Code colour;
9453             std::string passOrFail;
9454             std::string messageLabel;
9455             std::string message;
9456             std::vector<MessageInfo> messages;
9457             bool printInfoMessages;
9458         };
9459 
lazyPrintCatch::ConsoleReporter9460         void lazyPrint() {
9461 
9462             if( !currentTestRunInfo.used )
9463                 lazyPrintRunInfo();
9464             if( !currentGroupInfo.used )
9465                 lazyPrintGroupInfo();
9466 
9467             if( !m_headerPrinted ) {
9468                 printTestCaseAndSectionHeader();
9469                 m_headerPrinted = true;
9470             }
9471         }
lazyPrintRunInfoCatch::ConsoleReporter9472         void lazyPrintRunInfo() {
9473             stream  << "\n" << getLineOfChars<'~'>() << "\n";
9474             Colour colour( Colour::SecondaryText );
9475             stream  << currentTestRunInfo->name
9476                     << " is a Catch v"  << libraryVersion << " host application.\n"
9477                     << "Run with -? for options\n\n";
9478 
9479             if( m_config->rngSeed() != 0 )
9480                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
9481 
9482             currentTestRunInfo.used = true;
9483         }
lazyPrintGroupInfoCatch::ConsoleReporter9484         void lazyPrintGroupInfo() {
9485             if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
9486                 printClosedHeader( "Group: " + currentGroupInfo->name );
9487                 currentGroupInfo.used = true;
9488             }
9489         }
printTestCaseAndSectionHeaderCatch::ConsoleReporter9490         void printTestCaseAndSectionHeader() {
9491             assert( !m_sectionStack.empty() );
9492             printOpenHeader( currentTestCaseInfo->name );
9493 
9494             if( m_sectionStack.size() > 1 ) {
9495                 Colour colourGuard( Colour::Headers );
9496 
9497                 std::vector<SectionInfo>::const_iterator
9498                     it = m_sectionStack.begin()+1, // Skip first section (test case)
9499                     itEnd = m_sectionStack.end();
9500                 for( ; it != itEnd; ++it )
9501                     printHeaderString( it->name, 2 );
9502             }
9503 
9504             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
9505 
9506             if( !lineInfo.empty() ){
9507                 stream << getLineOfChars<'-'>() << "\n";
9508                 Colour colourGuard( Colour::FileName );
9509                 stream << lineInfo << "\n";
9510             }
9511             stream << getLineOfChars<'.'>() << "\n" << std::endl;
9512         }
9513 
printClosedHeaderCatch::ConsoleReporter9514         void printClosedHeader( std::string const& _name ) {
9515             printOpenHeader( _name );
9516             stream << getLineOfChars<'.'>() << "\n";
9517         }
printOpenHeaderCatch::ConsoleReporter9518         void printOpenHeader( std::string const& _name ) {
9519             stream  << getLineOfChars<'-'>() << "\n";
9520             {
9521                 Colour colourGuard( Colour::Headers );
9522                 printHeaderString( _name );
9523             }
9524         }
9525 
9526         // if string has a : in first line will set indent to follow it on
9527         // subsequent lines
printHeaderStringCatch::ConsoleReporter9528         void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
9529             std::size_t i = _string.find( ": " );
9530             if( i != std::string::npos )
9531                 i+=2;
9532             else
9533                 i = 0;
9534             stream << Text( _string, TextAttributes()
9535                                         .setIndent( indent+i)
9536                                         .setInitialIndent( indent ) ) << "\n";
9537         }
9538 
9539         struct SummaryColumn {
9540 
SummaryColumnCatch::ConsoleReporter::SummaryColumn9541             SummaryColumn( std::string const& _label, Colour::Code _colour )
9542             :   label( _label ),
9543                 colour( _colour )
9544             {}
addRowCatch::ConsoleReporter::SummaryColumn9545             SummaryColumn addRow( std::size_t count ) {
9546                 std::ostringstream oss;
9547                 oss << count;
9548                 std::string row = oss.str();
9549                 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
9550                     while( it->size() < row.size() )
9551                         *it = " " + *it;
9552                     while( it->size() > row.size() )
9553                         row = " " + row;
9554                 }
9555                 rows.push_back( row );
9556                 return *this;
9557             }
9558 
9559             std::string label;
9560             Colour::Code colour;
9561             std::vector<std::string> rows;
9562 
9563         };
9564 
printTotalsCatch::ConsoleReporter9565         void printTotals( Totals const& totals ) {
9566             if( totals.testCases.total() == 0 ) {
9567                 stream << Colour( Colour::Warning ) << "No tests ran\n";
9568             }
9569             else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
9570                 stream << Colour( Colour::ResultSuccess ) << "All tests passed";
9571                 stream << " ("
9572                         << pluralise( totals.assertions.passed, "assertion" ) << " in "
9573                         << pluralise( totals.testCases.passed, "test case" ) << ")"
9574                         << "\n";
9575             }
9576             else {
9577 
9578                 std::vector<SummaryColumn> columns;
9579                 columns.push_back( SummaryColumn( "", Colour::None )
9580                                         .addRow( totals.testCases.total() )
9581                                         .addRow( totals.assertions.total() ) );
9582                 columns.push_back( SummaryColumn( "passed", Colour::Success )
9583                                         .addRow( totals.testCases.passed )
9584                                         .addRow( totals.assertions.passed ) );
9585                 columns.push_back( SummaryColumn( "failed", Colour::ResultError )
9586                                         .addRow( totals.testCases.failed )
9587                                         .addRow( totals.assertions.failed ) );
9588                 columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
9589                                         .addRow( totals.testCases.failedButOk )
9590                                         .addRow( totals.assertions.failedButOk ) );
9591 
9592                 printSummaryRow( "test cases", columns, 0 );
9593                 printSummaryRow( "assertions", columns, 1 );
9594             }
9595         }
printSummaryRowCatch::ConsoleReporter9596         void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
9597             for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
9598                 std::string value = it->rows[row];
9599                 if( it->label.empty() ) {
9600                     stream << label << ": ";
9601                     if( value != "0" )
9602                         stream << value;
9603                     else
9604                         stream << Colour( Colour::Warning ) << "- none -";
9605                 }
9606                 else if( value != "0" ) {
9607                     stream  << Colour( Colour::LightGrey ) << " | ";
9608                     stream  << Colour( it->colour )
9609                             << value << " " << it->label;
9610                 }
9611             }
9612             stream << "\n";
9613         }
9614 
makeRatioCatch::ConsoleReporter9615         static std::size_t makeRatio( std::size_t number, std::size_t total ) {
9616             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
9617             return ( ratio == 0 && number > 0 ) ? 1 : ratio;
9618         }
findMaxCatch::ConsoleReporter9619         static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
9620             if( i > j && i > k )
9621                 return i;
9622             else if( j > k )
9623                 return j;
9624             else
9625                 return k;
9626         }
9627 
printTotalsDividerCatch::ConsoleReporter9628         void printTotalsDivider( Totals const& totals ) {
9629             if( totals.testCases.total() > 0 ) {
9630                 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
9631                 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
9632                 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
9633                 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
9634                     findMax( failedRatio, failedButOkRatio, passedRatio )++;
9635                 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
9636                     findMax( failedRatio, failedButOkRatio, passedRatio )--;
9637 
9638                 stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
9639                 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
9640                 if( totals.testCases.allPassed() )
9641                     stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
9642                 else
9643                     stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
9644             }
9645             else {
9646                 stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
9647             }
9648             stream << "\n";
9649         }
printSummaryDividerCatch::ConsoleReporter9650         void printSummaryDivider() {
9651             stream << getLineOfChars<'-'>() << "\n";
9652         }
9653 
9654     private:
9655         bool m_headerPrinted;
9656     };
9657 
9658     INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
9659 
9660 } // end namespace Catch
9661 
9662 // #included from: ../reporters/catch_reporter_compact.hpp
9663 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
9664 
9665 namespace Catch {
9666 
9667     struct CompactReporter : StreamingReporterBase {
9668 
CompactReporterCatch::CompactReporter9669         CompactReporter( ReporterConfig const& _config )
9670         : StreamingReporterBase( _config )
9671         {}
9672 
9673         virtual ~CompactReporter();
9674 
getDescriptionCatch::CompactReporter9675         static std::string getDescription() {
9676             return "Reports test results on a single line, suitable for IDEs";
9677         }
9678 
getPreferencesCatch::CompactReporter9679         virtual ReporterPreferences getPreferences() const {
9680             ReporterPreferences prefs;
9681             prefs.shouldRedirectStdOut = false;
9682             return prefs;
9683         }
9684 
noMatchingTestCasesCatch::CompactReporter9685         virtual void noMatchingTestCases( std::string const& spec ) {
9686             stream << "No test cases matched '" << spec << "'" << std::endl;
9687         }
9688 
assertionStartingCatch::CompactReporter9689         virtual void assertionStarting( AssertionInfo const& ) {
9690         }
9691 
assertionEndedCatch::CompactReporter9692         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
9693             AssertionResult const& result = _assertionStats.assertionResult;
9694 
9695             bool printInfoMessages = true;
9696 
9697             // Drop out if result was successful and we're not printing those
9698             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9699                 if( result.getResultType() != ResultWas::Warning )
9700                     return false;
9701                 printInfoMessages = false;
9702             }
9703 
9704             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9705             printer.print();
9706 
9707             stream << std::endl;
9708             return true;
9709         }
9710 
testRunEndedCatch::CompactReporter9711         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
9712             printTotals( _testRunStats.totals );
9713             stream << "\n" << std::endl;
9714             StreamingReporterBase::testRunEnded( _testRunStats );
9715         }
9716 
9717     private:
9718         class AssertionPrinter {
9719             void operator= ( AssertionPrinter const& );
9720         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)9721             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
9722             : stream( _stream )
9723             , stats( _stats )
9724             , result( _stats.assertionResult )
9725             , messages( _stats.infoMessages )
9726             , itMessage( _stats.infoMessages.begin() )
9727             , printInfoMessages( _printInfoMessages )
9728             {}
9729 
print()9730             void print() {
9731                 printSourceInfo();
9732 
9733                 itMessage = messages.begin();
9734 
9735                 switch( result.getResultType() ) {
9736                     case ResultWas::Ok:
9737                         printResultType( Colour::ResultSuccess, passedString() );
9738                         printOriginalExpression();
9739                         printReconstructedExpression();
9740                         if ( ! result.hasExpression() )
9741                             printRemainingMessages( Colour::None );
9742                         else
9743                             printRemainingMessages();
9744                         break;
9745                     case ResultWas::ExpressionFailed:
9746                         if( result.isOk() )
9747                             printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
9748                         else
9749                             printResultType( Colour::Error, failedString() );
9750                         printOriginalExpression();
9751                         printReconstructedExpression();
9752                         printRemainingMessages();
9753                         break;
9754                     case ResultWas::ThrewException:
9755                         printResultType( Colour::Error, failedString() );
9756                         printIssue( "unexpected exception with message:" );
9757                         printMessage();
9758                         printExpressionWas();
9759                         printRemainingMessages();
9760                         break;
9761                     case ResultWas::FatalErrorCondition:
9762                         printResultType( Colour::Error, failedString() );
9763                         printIssue( "fatal error condition with message:" );
9764                         printMessage();
9765                         printExpressionWas();
9766                         printRemainingMessages();
9767                         break;
9768                     case ResultWas::DidntThrowException:
9769                         printResultType( Colour::Error, failedString() );
9770                         printIssue( "expected exception, got none" );
9771                         printExpressionWas();
9772                         printRemainingMessages();
9773                         break;
9774                     case ResultWas::Info:
9775                         printResultType( Colour::None, "info" );
9776                         printMessage();
9777                         printRemainingMessages();
9778                         break;
9779                     case ResultWas::Warning:
9780                         printResultType( Colour::None, "warning" );
9781                         printMessage();
9782                         printRemainingMessages();
9783                         break;
9784                     case ResultWas::ExplicitFailure:
9785                         printResultType( Colour::Error, failedString() );
9786                         printIssue( "explicitly" );
9787                         printRemainingMessages( Colour::None );
9788                         break;
9789                     // These cases are here to prevent compiler warnings
9790                     case ResultWas::Unknown:
9791                     case ResultWas::FailureBit:
9792                     case ResultWas::Exception:
9793                         printResultType( Colour::Error, "** internal error **" );
9794                         break;
9795                 }
9796             }
9797 
9798         private:
9799             // Colour::LightGrey
9800 
dimColour()9801             static Colour::Code dimColour() { return Colour::FileName; }
9802 
9803 #ifdef CATCH_PLATFORM_MAC
failedString()9804             static const char* failedString() { return "FAILED"; }
passedString()9805             static const char* passedString() { return "PASSED"; }
9806 #else
failedString()9807             static const char* failedString() { return "failed"; }
passedString()9808             static const char* passedString() { return "passed"; }
9809 #endif
9810 
printSourceInfo() const9811             void printSourceInfo() const {
9812                 Colour colourGuard( Colour::FileName );
9813                 stream << result.getSourceInfo() << ":";
9814             }
9815 
printResultType(Colour::Code colour,std::string passOrFail) const9816             void printResultType( Colour::Code colour, std::string passOrFail ) const {
9817                 if( !passOrFail.empty() ) {
9818                     {
9819                         Colour colourGuard( colour );
9820                         stream << " " << passOrFail;
9821                     }
9822                     stream << ":";
9823                 }
9824             }
9825 
printIssue(std::string issue) const9826             void printIssue( std::string issue ) const {
9827                 stream << " " << issue;
9828             }
9829 
printExpressionWas()9830             void printExpressionWas() {
9831                 if( result.hasExpression() ) {
9832                     stream << ";";
9833                     {
9834                         Colour colour( dimColour() );
9835                         stream << " expression was:";
9836                     }
9837                     printOriginalExpression();
9838                 }
9839             }
9840 
printOriginalExpression() const9841             void printOriginalExpression() const {
9842                 if( result.hasExpression() ) {
9843                     stream << " " << result.getExpression();
9844                 }
9845             }
9846 
printReconstructedExpression() const9847             void printReconstructedExpression() const {
9848                 if( result.hasExpandedExpression() ) {
9849                     {
9850                         Colour colour( dimColour() );
9851                         stream << " for: ";
9852                     }
9853                     stream << result.getExpandedExpression();
9854                 }
9855             }
9856 
printMessage()9857             void printMessage() {
9858                 if ( itMessage != messages.end() ) {
9859                     stream << " '" << itMessage->message << "'";
9860                     ++itMessage;
9861                 }
9862             }
9863 
printRemainingMessages(Colour::Code colour=dimColour ())9864             void printRemainingMessages( Colour::Code colour = dimColour() ) {
9865                 if ( itMessage == messages.end() )
9866                     return;
9867 
9868                 // using messages.end() directly yields compilation error:
9869                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
9870                 const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
9871 
9872                 {
9873                     Colour colourGuard( colour );
9874                     stream << " with " << pluralise( N, "message" ) << ":";
9875                 }
9876 
9877                 for(; itMessage != itEnd; ) {
9878                     // If this assertion is a warning ignore any INFO messages
9879                     if( printInfoMessages || itMessage->type != ResultWas::Info ) {
9880                         stream << " '" << itMessage->message << "'";
9881                         if ( ++itMessage != itEnd ) {
9882                             Colour colourGuard( dimColour() );
9883                             stream << " and";
9884                         }
9885                     }
9886                 }
9887             }
9888 
9889         private:
9890             std::ostream& stream;
9891             AssertionStats const& stats;
9892             AssertionResult const& result;
9893             std::vector<MessageInfo> messages;
9894             std::vector<MessageInfo>::const_iterator itMessage;
9895             bool printInfoMessages;
9896         };
9897 
9898         // Colour, message variants:
9899         // - white: No tests ran.
9900         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
9901         // - white: Passed [both/all] N test cases (no assertions).
9902         // -   red: Failed N tests cases, failed M assertions.
9903         // - green: Passed [both/all] N tests cases with M assertions.
9904 
bothOrAllCatch::CompactReporter9905         std::string bothOrAll( std::size_t count ) const {
9906             return count == 1 ? "" : count == 2 ? "both " : "all " ;
9907         }
9908 
printTotalsCatch::CompactReporter9909         void printTotals( const Totals& totals ) const {
9910             if( totals.testCases.total() == 0 ) {
9911                 stream << "No tests ran.";
9912             }
9913             else if( totals.testCases.failed == totals.testCases.total() ) {
9914                 Colour colour( Colour::ResultError );
9915                 const std::string qualify_assertions_failed =
9916                     totals.assertions.failed == totals.assertions.total() ?
9917                         bothOrAll( totals.assertions.failed ) : "";
9918                 stream <<
9919                     "Failed " << bothOrAll( totals.testCases.failed )
9920                               << pluralise( totals.testCases.failed, "test case"  ) << ", "
9921                     "failed " << qualify_assertions_failed <<
9922                                  pluralise( totals.assertions.failed, "assertion" ) << ".";
9923             }
9924             else if( totals.assertions.total() == 0 ) {
9925                 stream <<
9926                     "Passed " << bothOrAll( totals.testCases.total() )
9927                               << pluralise( totals.testCases.total(), "test case" )
9928                               << " (no assertions).";
9929             }
9930             else if( totals.assertions.failed ) {
9931                 Colour colour( Colour::ResultError );
9932                 stream <<
9933                     "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
9934                     "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
9935             }
9936             else {
9937                 Colour colour( Colour::ResultSuccess );
9938                 stream <<
9939                     "Passed " << bothOrAll( totals.testCases.passed )
9940                               << pluralise( totals.testCases.passed, "test case"  ) <<
9941                     " with "  << pluralise( totals.assertions.passed, "assertion" ) << ".";
9942             }
9943         }
9944     };
9945 
9946     INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
9947 
9948 } // end namespace Catch
9949 
9950 namespace Catch {
9951     // These are all here to avoid warnings about not having any out of line
9952     // virtual methods
~NonCopyable()9953     NonCopyable::~NonCopyable() {}
~IShared()9954     IShared::~IShared() {}
~IStream()9955     IStream::~IStream() CATCH_NOEXCEPT {}
~FileStream()9956     FileStream::~FileStream() CATCH_NOEXCEPT {}
~CoutStream()9957     CoutStream::~CoutStream() CATCH_NOEXCEPT {}
~DebugOutStream()9958     DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
~StreamBufBase()9959     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
~IContext()9960     IContext::~IContext() {}
~IResultCapture()9961     IResultCapture::~IResultCapture() {}
~ITestCase()9962     ITestCase::~ITestCase() {}
~ITestCaseRegistry()9963     ITestCaseRegistry::~ITestCaseRegistry() {}
~IRegistryHub()9964     IRegistryHub::~IRegistryHub() {}
~IMutableRegistryHub()9965     IMutableRegistryHub::~IMutableRegistryHub() {}
~IExceptionTranslator()9966     IExceptionTranslator::~IExceptionTranslator() {}
~IExceptionTranslatorRegistry()9967     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
~IReporter()9968     IReporter::~IReporter() {}
~IReporterFactory()9969     IReporterFactory::~IReporterFactory() {}
~IReporterRegistry()9970     IReporterRegistry::~IReporterRegistry() {}
~IStreamingReporter()9971     IStreamingReporter::~IStreamingReporter() {}
~AssertionStats()9972     AssertionStats::~AssertionStats() {}
~SectionStats()9973     SectionStats::~SectionStats() {}
~TestCaseStats()9974     TestCaseStats::~TestCaseStats() {}
~TestGroupStats()9975     TestGroupStats::~TestGroupStats() {}
~TestRunStats()9976     TestRunStats::~TestRunStats() {}
~SectionNode()9977     CumulativeReporterBase::SectionNode::~SectionNode() {}
~CumulativeReporterBase()9978     CumulativeReporterBase::~CumulativeReporterBase() {}
9979 
~StreamingReporterBase()9980     StreamingReporterBase::~StreamingReporterBase() {}
~ConsoleReporter()9981     ConsoleReporter::~ConsoleReporter() {}
~CompactReporter()9982     CompactReporter::~CompactReporter() {}
~IRunner()9983     IRunner::~IRunner() {}
~IMutableContext()9984     IMutableContext::~IMutableContext() {}
~IConfig()9985     IConfig::~IConfig() {}
~XmlReporter()9986     XmlReporter::~XmlReporter() {}
~JunitReporter()9987     JunitReporter::~JunitReporter() {}
~TestRegistry()9988     TestRegistry::~TestRegistry() {}
~FreeFunctionTestCase()9989     FreeFunctionTestCase::~FreeFunctionTestCase() {}
~IGeneratorInfo()9990     IGeneratorInfo::~IGeneratorInfo() {}
~IGeneratorsForTest()9991     IGeneratorsForTest::~IGeneratorsForTest() {}
~WildcardPattern()9992     WildcardPattern::~WildcardPattern() {}
~Pattern()9993     TestSpec::Pattern::~Pattern() {}
~NamePattern()9994     TestSpec::NamePattern::~NamePattern() {}
~TagPattern()9995     TestSpec::TagPattern::~TagPattern() {}
~ExcludedPattern()9996     TestSpec::ExcludedPattern::~ExcludedPattern() {}
9997 
~Equals()9998     Matchers::Impl::StdString::Equals::~Equals() {}
~Contains()9999     Matchers::Impl::StdString::Contains::~Contains() {}
~StartsWith()10000     Matchers::Impl::StdString::StartsWith::~StartsWith() {}
~EndsWith()10001     Matchers::Impl::StdString::EndsWith::~EndsWith() {}
10002 
dummy()10003     void Config::dummy() {}
10004 
10005     namespace TestCaseTracking {
~ITracker()10006         ITracker::~ITracker() {}
~TrackerBase()10007         TrackerBase::~TrackerBase() {}
~SectionTracker()10008         SectionTracker::~SectionTracker() {}
~IndexTracker()10009         IndexTracker::~IndexTracker() {}
10010     }
10011 }
10012 
10013 #ifdef __clang__
10014 #pragma clang diagnostic pop
10015 #endif
10016 
10017 #endif
10018 
10019 #ifdef CATCH_CONFIG_MAIN
10020 // #included from: internal/catch_default_main.hpp
10021 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
10022 
10023 #ifndef __OBJC__
10024 
10025 // Standard C/C++ main entry point
main(int argc,char * argv[])10026 int main (int argc, char * argv[]) {
10027     return Catch::Session().run( argc, argv );
10028 }
10029 
10030 #else // __OBJC__
10031 
10032 // Objective-C entry point
main(int argc,char * const argv[])10033 int main (int argc, char * const argv[]) {
10034 #if !CATCH_ARC_ENABLED
10035     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
10036 #endif
10037 
10038     Catch::registerTestMethods();
10039     int result = Catch::Session().run( argc, (char* const*)argv );
10040 
10041 #if !CATCH_ARC_ENABLED
10042     [pool drain];
10043 #endif
10044 
10045     return result;
10046 }
10047 
10048 #endif // __OBJC__
10049 
10050 #endif
10051 
10052 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
10053 #  undef CLARA_CONFIG_MAIN
10054 #endif
10055 
10056 //////
10057 
10058 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
10059 #ifdef CATCH_CONFIG_PREFIX_ALL
10060 
10061 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
10062 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
10063 
10064 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
10065 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
10066 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
10067 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
10068 
10069 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
10070 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
10071 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
10072 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
10073 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
10074 
10075 #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
10076 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
10077 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
10078 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
10079 
10080 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
10081 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
10082 
10083 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10084 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
10085 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10086 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10087 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10088 
10089 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10090     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10091     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10092     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10093     #define CATCH_REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
10094     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10095     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
10096     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
10097 #else
10098     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10099     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10100     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10101     #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
10102     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10103     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
10104     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
10105 #endif
10106 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10107 
10108 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10109 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10110 
10111 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10112 
10113 // "BDD-style" convenience wrappers
10114 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10115 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
10116 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10117 #else
10118 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
10119 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10120 #endif
10121 #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
10122 #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
10123 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
10124 #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
10125 #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
10126 
10127 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
10128 #else
10129 
10130 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
10131 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
10132 
10133 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
10134 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
10135 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
10136 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
10137 
10138 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
10139 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
10140 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
10141 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
10142 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
10143 
10144 #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
10145 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
10146 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
10147 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
10148 
10149 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
10150 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
10151 
10152 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10153 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
10154 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10155 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10156 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10157 
10158 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10159     #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10160     #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10161     #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10162     #define REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
10163     #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10164     #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
10165     #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
10166 #else
10167     #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10168     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10169     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10170     #define REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
10171     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10172     #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
10173     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
10174 #endif
10175 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10176 
10177 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10178 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10179 
10180 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10181 
10182 #endif
10183 
10184 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
10185 
10186 // "BDD-style" convenience wrappers
10187 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10188 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
10189 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10190 #else
10191 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
10192 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10193 #endif
10194 #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
10195 #define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
10196 #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
10197 #define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
10198 #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
10199 
10200 using Catch::Detail::Approx;
10201 
10202 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
10203 
10204