GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/unittests/catch.hpp Lines: 1242 3106 40.0 %
Date: 2021-03-17 Branches: 1838 6385 28.8 %

Line Branch Exec Source
1
/*
2
 *  Catch v1.5.1
3
 *  Generated: 2016-04-28 08:12:37.387488
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
#ifdef CATCH_CONFIG_COUNTER
66
#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
67
#else
68
#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
69
#endif
70
71
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
72
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
73
74
#include <sstream>
75
#include <stdexcept>
76
#include <algorithm>
77
78
// stack
79
#ifdef HAVE_EXECINFO
80
#include <execinfo.h>
81
#endif  // HAVE_EXECINFO
82
// stack
83
84
// #included from: catch_compiler_capabilities.h
85
#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
86
87
// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
88
// The following features are defined:
89
//
90
// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
91
// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
92
// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
93
// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
94
// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
95
// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
96
// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
97
// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
98
99
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
100
101
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
102
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
103
// ****************
104
// Note to maintainers: if new toggles are added please document them
105
// in configuration.md, too
106
// ****************
107
108
// In general each macro has a _NO_<feature name> form
109
// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
110
// Many features, at point of detection, define an _INTERNAL_ macro, so they
111
// can be combined, en-mass, with the _NO_ forms later.
112
113
// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
114
115
#if defined(__cplusplus) && __cplusplus >= 201103L
116
#  define CATCH_CPP11_OR_GREATER
117
#endif
118
119
#ifdef __clang__
120
121
#  if __has_feature(cxx_nullptr)
122
#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
123
#  endif
124
125
#  if __has_feature(cxx_noexcept)
126
#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
127
#  endif
128
129
#   if defined(CATCH_CPP11_OR_GREATER)
130
#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
131
#   endif
132
133
#endif // __clang__
134
135
////////////////////////////////////////////////////////////////////////////////
136
// Borland
137
#ifdef __BORLANDC__
138
139
#endif // __BORLANDC__
140
141
////////////////////////////////////////////////////////////////////////////////
142
// EDG
143
#ifdef __EDG_VERSION__
144
145
#endif // __EDG_VERSION__
146
147
////////////////////////////////////////////////////////////////////////////////
148
// Digital Mars
149
#ifdef __DMC__
150
151
#endif // __DMC__
152
153
////////////////////////////////////////////////////////////////////////////////
154
// GCC
155
#ifdef __GNUC__
156
157
#   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
158
#       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
159
#   endif
160
161
#   if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
162
#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
163
#   endif
164
165
// - otherwise more recent versions define __cplusplus >= 201103L
166
// and will get picked up below
167
168
#endif // __GNUC__
169
170
////////////////////////////////////////////////////////////////////////////////
171
// Visual C++
172
#ifdef _MSC_VER
173
174
#if (_MSC_VER >= 1600)
175
#   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
176
#   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
177
#endif
178
179
#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
180
#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
181
#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
182
#endif
183
184
#endif // _MSC_VER
185
186
////////////////////////////////////////////////////////////////////////////////
187
188
// Use variadic macros if the compiler supports them
189
#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
190
    ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
191
    ( defined __GNUC__ && __GNUC__ >= 3 ) || \
192
    ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
193
194
#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
195
196
#endif
197
198
// Use __COUNTER__ if the compiler supports it
199
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
200
    ( defined __GNUC__  && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
201
    ( defined __clang__ && __clang_major__ >= 3 )
202
203
#define CATCH_INTERNAL_CONFIG_COUNTER
204
205
#endif
206
207
////////////////////////////////////////////////////////////////////////////////
208
// C++ language feature support
209
210
// catch all support for C++11
211
#if defined(CATCH_CPP11_OR_GREATER)
212
213
#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
214
#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
215
#  endif
216
217
#  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
218
#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
219
#  endif
220
221
#  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
222
#    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
223
#  endif
224
225
#  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
226
#    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
227
#  endif
228
229
#  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
230
#    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
231
#  endif
232
233
#  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
234
#    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
235
#  endif
236
237
#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
238
#    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
239
#  endif
240
241
#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
242
#    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
243
#  endif
244
#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
245
#    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
246
#  endif
247
248
#endif // __cplusplus >= 201103L
249
250
// Now set the actual defines based on the above + anything the user has configured
251
#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
252
#   define CATCH_CONFIG_CPP11_NULLPTR
253
#endif
254
#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
255
#   define CATCH_CONFIG_CPP11_NOEXCEPT
256
#endif
257
#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)
258
#   define CATCH_CONFIG_CPP11_GENERATED_METHODS
259
#endif
260
#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)
261
#   define CATCH_CONFIG_CPP11_IS_ENUM
262
#endif
263
#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
264
#   define CATCH_CONFIG_CPP11_TUPLE
265
#endif
266
#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
267
#   define CATCH_CONFIG_VARIADIC_MACROS
268
#endif
269
#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)
270
#   define CATCH_CONFIG_CPP11_LONG_LONG
271
#endif
272
#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
273
#   define CATCH_CONFIG_CPP11_OVERRIDE
274
#endif
275
#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)
276
#   define CATCH_CONFIG_CPP11_UNIQUE_PTR
277
#endif
278
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
279
#   define CATCH_CONFIG_COUNTER
280
#endif
281
282
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
283
#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
284
#endif
285
286
// noexcept support:
287
#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
288
#  define CATCH_NOEXCEPT noexcept
289
#  define CATCH_NOEXCEPT_IS(x) noexcept(x)
290
#else
291
#  define CATCH_NOEXCEPT throw()
292
#  define CATCH_NOEXCEPT_IS(x)
293
#endif
294
295
// nullptr support
296
#ifdef CATCH_CONFIG_CPP11_NULLPTR
297
#   define CATCH_NULL nullptr
298
#else
299
#   define CATCH_NULL NULL
300
#endif
301
302
// override support
303
#ifdef CATCH_CONFIG_CPP11_OVERRIDE
304
#   define CATCH_OVERRIDE override
305
#else
306
#   define CATCH_OVERRIDE
307
#endif
308
309
// unique_ptr support
310
#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
311
#   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
312
#else
313
#   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
314
#endif
315
316
namespace Catch {
317
318
    struct IConfig;
319
320
    struct CaseSensitive { enum Choice {
321
        Yes,
322
        No
323
    }; };
324
325
    class NonCopyable {
326
#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
327
        NonCopyable( NonCopyable const& )              = delete;
328
        NonCopyable( NonCopyable && )                  = delete;
329
        NonCopyable& operator = ( NonCopyable const& ) = delete;
330
        NonCopyable& operator = ( NonCopyable && )     = delete;
331
#else
332
        NonCopyable( NonCopyable const& info );
333
        NonCopyable& operator = ( NonCopyable const& );
334
#endif
335
336
    protected:
337
10027
        NonCopyable() {}
338
        virtual ~NonCopyable();
339
    };
340
341
    class SafeBool {
342
    public:
343
        typedef void (SafeBool::*type)() const;
344
345
        static type makeSafe( bool value ) {
346


3
            return value ? &SafeBool::trueValue : 0;
347
        }
348
    private:
349
        void trueValue() const {}
350
    };
351
352
    template<typename ContainerT>
353
    inline void deleteAll( ContainerT& container ) {
354
2
        typename ContainerT::const_iterator it = container.begin();
355
2
        typename ContainerT::const_iterator itEnd = container.end();
356

1
        for(; it != itEnd; ++it )
357
            delete *it;
358
    }
359
    template<typename AssociativeContainerT>
360
    inline void deleteAllValues( AssociativeContainerT& container ) {
361
        typename AssociativeContainerT::const_iterator it = container.begin();
362
        typename AssociativeContainerT::const_iterator itEnd = container.end();
363
        for(; it != itEnd; ++it )
364
            delete it->second;
365
    }
366
367
    bool startsWith( std::string const& s, std::string const& prefix );
368
    bool endsWith( std::string const& s, std::string const& suffix );
369
    bool contains( std::string const& s, std::string const& infix );
370
    void toLowerInPlace( std::string& s );
371
    std::string toLower( std::string const& s );
372
    std::string trim( std::string const& str );
373
    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
374
375
4
    struct pluralise {
376
        pluralise( std::size_t count, std::string const& label );
377
378
        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
379
380
        std::size_t m_count;
381
        std::string m_label;
382
    };
383
384

18697602
    struct SourceLineInfo {
385
386
        SourceLineInfo();
387
        SourceLineInfo( char const* _file, std::size_t _line );
388
        SourceLineInfo( SourceLineInfo const& other );
389
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
390
2
        SourceLineInfo( SourceLineInfo && )                  = default;
391
        SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
392
        SourceLineInfo& operator = ( SourceLineInfo && )     = default;
393
#  endif
394
        bool empty() const;
395
        bool operator == ( SourceLineInfo const& other ) const;
396
        bool operator < ( SourceLineInfo const& other ) const;
397
398
        std::string file;
399
        std::size_t line;
400
    };
401
402
    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
403
404
    // This is just here to avoid compiler warnings with macro constants and boolean literals
405
    inline bool isTrue( bool value ){ return value; }
406
    inline bool alwaysTrue() { return true; }
407
    inline bool alwaysFalse() { return false; }
408
409
    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
410
411
    void seedRng( IConfig const& config );
412
    unsigned int rngSeed();
413
414
    // Use this in variadic streaming macros to allow
415
    //    >> +StreamEndStop
416
    // as well as
417
    //    >> stuff +StreamEndStop
418
    struct StreamEndStop {
419
        std::string operator+() {
420
            return std::string();
421
        }
422
    };
423
    template<typename T>
424
    T const& operator + ( T const& value, StreamEndStop ) {
425
        return value;
426
    }
427
}
428
429
#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
430
#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
431
432
#include <ostream>
433
434
namespace Catch {
435
436
    class NotImplementedException : public std::exception
437
    {
438
    public:
439
        NotImplementedException( SourceLineInfo const& lineInfo );
440
        NotImplementedException( NotImplementedException const& ) {}
441
442
        virtual ~NotImplementedException() CATCH_NOEXCEPT {}
443
444
        virtual const char* what() const CATCH_NOEXCEPT;
445
446
    private:
447
        std::string m_what;
448
        SourceLineInfo m_lineInfo;
449
    };
450
451
} // end namespace Catch
452
453
///////////////////////////////////////////////////////////////////////////////
454
#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
455
456
// #included from: internal/catch_context.h
457
#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
458
459
// #included from: catch_interfaces_generators.h
460
#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
461
462
#include <string>
463
464
namespace Catch {
465
466
    struct IGeneratorInfo {
467
        virtual ~IGeneratorInfo();
468
        virtual bool moveNext() = 0;
469
        virtual std::size_t getCurrentIndex() const = 0;
470
    };
471
472
    struct IGeneratorsForTest {
473
        virtual ~IGeneratorsForTest();
474
475
        virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
476
        virtual bool moveNext() = 0;
477
    };
478
479
    IGeneratorsForTest* createGeneratorsForTest();
480
481
} // end namespace Catch
482
483
// #included from: catch_ptr.hpp
484
#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
485
486
#ifdef __clang__
487
#pragma clang diagnostic push
488
#pragma clang diagnostic ignored "-Wpadded"
489
#endif
490
491
namespace Catch {
492
493
    // An intrusive reference counting smart pointer.
494
    // T must implement addRef() and release() methods
495
    // typically implementing the IShared interface
496
    template<typename T>
497
    class Ptr {
498
    public:
499
4
        Ptr() : m_p( CATCH_NULL ){}
500
1607
        Ptr( T* p ) : m_p( p ){
501













1606
            if( m_p )
502


1606
                m_p->addRef();
503
        }
504
167158
        Ptr( Ptr const& other ) : m_p( other.m_p ){
505























167158
            if( m_p )
506















167158
                m_p->addRef();
507
        }
508
        ~Ptr(){
509


































































168769
            if( m_p )
510
168764
                m_p->release();
511
3866
        }
512
        void reset() {
513

1
            if( m_p )
514
                m_p->release();
515
1
            m_p = CATCH_NULL;
516
        }
517
        Ptr& operator = ( T* p ){
518
792
            Ptr temp( p );
519
397
            swap( temp );
520
397
            return *this;
521
        }
522
4
        Ptr& operator = ( Ptr const& other ){
523
8
            Ptr temp( other );
524
4
            swap( temp );
525
8
            return *this;
526
        }
527
802
        void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
528
9099
        T* get() const{ return m_p; }
529
1550
        T& operator*() const { return *m_p; }
530
3231881
        T* operator->() const { return m_p; }
531
3
        bool operator !() const { return m_p == CATCH_NULL; }
532
4
        operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
533
534
    private:
535
        T* m_p;
536
    };
537
538
3270
    struct IShared : NonCopyable {
539
        virtual ~IShared();
540
        virtual void addRef() const = 0;
541
        virtual void release() const = 0;
542
    };
543
544
    template<typename T = IShared>
545
3270
    struct SharedImpl : T {
546
547
3270
        SharedImpl() : m_rc( 0 ){}
548
549
168764
        virtual void addRef() const {
550
168764
            ++m_rc;
551
168764
        }
552
168764
        virtual void release() const {
553


168764
            if( --m_rc == 0 )
554
1604
                delete this;
555
168764
        }
556
557
        mutable unsigned int m_rc;
558
    };
559
560
} // end namespace Catch
561
562
#ifdef __clang__
563
#pragma clang diagnostic pop
564
#endif
565
566
#include <memory>
567
#include <vector>
568
#include <stdlib.h>
569
570
namespace Catch {
571
572
    class TestCase;
573
    class Stream;
574
    struct IResultCapture;
575
    struct IRunner;
576
    struct IGeneratorsForTest;
577
    struct IConfig;
578
579
    struct IContext
580
    {
581
        virtual ~IContext();
582
583
        virtual IResultCapture* getResultCapture() = 0;
584
        virtual IRunner* getRunner() = 0;
585
        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
586
        virtual bool advanceGeneratorsForCurrentTest() = 0;
587
        virtual Ptr<IConfig const> getConfig() const = 0;
588
    };
589
590
1
    struct IMutableContext : IContext
591
    {
592
        virtual ~IMutableContext();
593
        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
594
        virtual void setRunner( IRunner* runner ) = 0;
595
        virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
596
    };
597
598
    IContext& getCurrentContext();
599
    IMutableContext& getCurrentMutableContext();
600
    void cleanUpContext();
601
    Stream createStream( std::string const& streamName );
602
603
}
604
605
// #included from: internal/catch_test_registry.hpp
606
#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
607
608
// #included from: catch_interfaces_testcase.h
609
#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
610
611
#include <vector>
612
613
namespace Catch {
614
615
    class TestSpec;
616
617
790
    struct ITestCase : IShared {
618
        virtual void invoke () const = 0;
619
    protected:
620
        virtual ~ITestCase();
621
    };
622
623
    class TestCase;
624
    struct IConfig;
625
626
    struct ITestCaseRegistry {
627
        virtual ~ITestCaseRegistry();
628
        virtual std::vector<TestCase> const& getAllTests() const = 0;
629
        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
630
    };
631
632
    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
633
    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
634
    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
635
636
}
637
638
namespace Catch {
639
640
template<typename C>
641
class MethodTestCase : public SharedImpl<ITestCase> {
642
643
public:
644
    MethodTestCase( void (C::*method)() ) : m_method( method ) {}
645
646
    virtual void invoke() const {
647
        C obj;
648
        (obj.*m_method)();
649
    }
650
651
private:
652
    virtual ~MethodTestCase() {}
653
654
    void (C::*m_method)();
655
};
656
657
typedef void(*TestFunction)();
658
659
struct NameAndDesc {
660
    NameAndDesc( const char* _name = "", const char* _description= "" )
661
395
    : name( _name ), description( _description )
662
    {}
663
664
    const char* name;
665
    const char* description;
666
};
667
668
void registerTestCase
669
    (   ITestCase* testCase,
670
        char const* className,
671
        NameAndDesc const& nameAndDesc,
672
        SourceLineInfo const& lineInfo );
673
674
struct AutoReg {
675
676
    AutoReg
677
        (   TestFunction function,
678
            SourceLineInfo const& lineInfo,
679
            NameAndDesc const& nameAndDesc );
680
681
    template<typename C>
682
    AutoReg
683
        (   void (C::*method)(),
684
            char const* className,
685
            NameAndDesc const& nameAndDesc,
686
            SourceLineInfo const& lineInfo ) {
687
688
        registerTestCase
689
            (   new MethodTestCase<C>( method ),
690
                className,
691
                nameAndDesc,
692
                lineInfo );
693
    }
694
695
    ~AutoReg();
696
697
private:
698
    AutoReg( AutoReg const& );
699
    void operator= ( AutoReg const& );
700
};
701
702
void registerTestCaseFunction
703
    (   TestFunction function,
704
        SourceLineInfo const& lineInfo,
705
        NameAndDesc const& nameAndDesc );
706
707
} // end namespace Catch
708
709
#ifdef CATCH_CONFIG_VARIADIC_MACROS
710
    ///////////////////////////////////////////////////////////////////////////////
711
    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
712
        static void TestName(); \
713
        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
714
        static void TestName()
715
    #define INTERNAL_CATCH_TESTCASE( ... ) \
716
        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
717
718
    ///////////////////////////////////////////////////////////////////////////////
719
    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
720
        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
721
722
    ///////////////////////////////////////////////////////////////////////////////
723
    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
724
        namespace{ \
725
            struct TestName : ClassName{ \
726
                void test(); \
727
            }; \
728
            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
729
        } \
730
        void TestName::test()
731
    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
732
        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
733
734
    ///////////////////////////////////////////////////////////////////////////////
735
    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
736
        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
737
738
#else
739
    ///////////////////////////////////////////////////////////////////////////////
740
    #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
741
        static void TestName(); \
742
        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
743
        static void TestName()
744
    #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
745
        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
746
747
    ///////////////////////////////////////////////////////////////////////////////
748
    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
749
        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
750
751
    ///////////////////////////////////////////////////////////////////////////////
752
    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
753
        namespace{ \
754
            struct TestCaseName : ClassName{ \
755
                void test(); \
756
            }; \
757
            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
758
        } \
759
        void TestCaseName::test()
760
    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
761
        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
762
763
    ///////////////////////////////////////////////////////////////////////////////
764
    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
765
        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
766
#endif
767
768
// #included from: internal/catch_capture.hpp
769
#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
770
771
// #included from: catch_result_builder.h
772
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
773
774
// #included from: catch_result_type.h
775
#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
776
777
namespace Catch {
778
779
    // ResultWas::OfType enum
780
    struct ResultWas { enum OfType {
781
        Unknown = -1,
782
        Ok = 0,
783
        Info = 1,
784
        Warning = 2,
785
786
        FailureBit = 0x10,
787
788
        ExpressionFailed = FailureBit | 1,
789
        ExplicitFailure = FailureBit | 2,
790
791
        Exception = 0x100 | FailureBit,
792
793
        ThrewException = Exception | 1,
794
        DidntThrowException = Exception | 2,
795
796
        FatalErrorCondition = 0x200 | FailureBit
797
798
    }; };
799
800
    inline bool isOk( ResultWas::OfType resultType ) {
801
2866004
        return ( resultType & ResultWas::FailureBit ) == 0;
802
    }
803
    inline bool isJustInfo( int flags ) {
804
        return flags == ResultWas::Info;
805
    }
806
807
    // ResultDisposition::Flags enum
808
    struct ResultDisposition { enum Flags {
809
        Normal = 0x01,
810
811
        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
812
        FalseTest = 0x04,           // Prefix expression with !
813
        SuppressFail = 0x08         // Failures are reported but do not fail the test
814
    }; };
815
816
    inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
817
        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
818
    }
819
820
    inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
821
1432971
    inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
822
    inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
823
824
} // end namespace Catch
825
826
// #included from: catch_assertionresult.h
827
#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
828
829
#include <string>
830
831
namespace Catch {
832
833
42994604
    struct AssertionInfo
834
    {
835
8
        AssertionInfo() {}
836
        AssertionInfo(  std::string const& _macroName,
837
                        SourceLineInfo const& _lineInfo,
838
                        std::string const& _capturedExpression,
839
                        ResultDisposition::Flags _resultDisposition );
840
841
        std::string macroName;
842
        SourceLineInfo lineInfo;
843
        std::string capturedExpression;
844
        ResultDisposition::Flags resultDisposition;
845
    };
846
847
34392051
    struct AssertionResultData
848
    {
849
4299009
        AssertionResultData() : resultType( ResultWas::Unknown ) {}
850
851
        std::string reconstructedExpression;
852
        std::string message;
853
        ResultWas::OfType resultType;
854
    };
855
856
2866004
    class AssertionResult {
857
    public:
858
        AssertionResult();
859
        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
860
        ~AssertionResult();
861
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
862
1433002
         AssertionResult( AssertionResult const& )              = default;
863
         AssertionResult( AssertionResult && )                  = default;
864
         AssertionResult& operator = ( AssertionResult const& ) = default;
865
         AssertionResult& operator = ( AssertionResult && )     = default;
866
#  endif
867
868
        bool isOk() const;
869
        bool succeeded() const;
870
        ResultWas::OfType getResultType() const;
871
        bool hasExpression() const;
872
        bool hasMessage() const;
873
        std::string getExpression() const;
874
        std::string getExpressionInMacro() const;
875
        bool hasExpandedExpression() const;
876
        std::string getExpandedExpression() const;
877
        std::string getMessage() const;
878
        SourceLineInfo getSourceInfo() const;
879
        std::string getTestMacroName() const;
880
881
    protected:
882
        AssertionInfo m_info;
883
        AssertionResultData m_resultData;
884
    };
885
886
} // end namespace Catch
887
888
// #included from: catch_matchers.hpp
889
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
890
891
namespace Catch {
892
namespace Matchers {
893
    namespace Impl {
894
895
    namespace Generic {
896
        template<typename ExpressionT> class AllOf;
897
        template<typename ExpressionT> class AnyOf;
898
        template<typename ExpressionT> class Not;
899
    }
900
901
    template<typename ExpressionT>
902
62
    struct Matcher : SharedImpl<IShared>
903
    {
904
        typedef ExpressionT ExpressionType;
905
906
62
        virtual ~Matcher() {}
907
        virtual Ptr<Matcher> clone() const = 0;
908
        virtual bool match( ExpressionT const& expr ) const = 0;
909
        virtual std::string toString() const = 0;
910
911
        Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
912
        Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
913
        Generic::Not<ExpressionT> operator ! () const;
914
    };
915
916
    template<typename DerivedT, typename ExpressionT>
917
124
    struct MatcherImpl : Matcher<ExpressionT> {
918
919
        virtual Ptr<Matcher<ExpressionT> > clone() const {
920
            return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
921
        }
922
    };
923
924
    namespace Generic {
925
        template<typename ExpressionT>
926
        class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
927
        public:
928
            explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
929
            Not( Not const& other ) : m_matcher( other.m_matcher ) {}
930
931
            virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
932
                return !m_matcher->match( expr );
933
            }
934
935
            virtual std::string toString() const CATCH_OVERRIDE {
936
                return "not " + m_matcher->toString();
937
            }
938
        private:
939
            Ptr< Matcher<ExpressionT> > m_matcher;
940
        };
941
942
        template<typename ExpressionT>
943
62
        class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
944
        public:
945
946
93
            AllOf() {}
947
            AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
948
949
            AllOf& add( Matcher<ExpressionT> const& matcher ) {
950
                m_matchers.push_back( matcher.clone() );
951
                return *this;
952
            }
953
31
            virtual bool match( ExpressionT const& expr ) const
954
            {
955
62
                for( std::size_t i = 0; i < m_matchers.size(); ++i )
956
                    if( !m_matchers[i]->match( expr ) )
957
                        return false;
958
                return true;
959
            }
960
            virtual std::string toString() const {
961
                std::ostringstream oss;
962
                oss << "( ";
963
                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
964
                    if( i != 0 )
965
                        oss << " and ";
966
                    oss << m_matchers[i]->toString();
967
                }
968
                oss << " )";
969
                return oss.str();
970
            }
971
972
            AllOf operator && ( Matcher<ExpressionT> const& other ) const {
973
                AllOf allOfExpr( *this );
974
                allOfExpr.add( other );
975
                return allOfExpr;
976
            }
977
978
        private:
979
            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
980
        };
981
982
        template<typename ExpressionT>
983
        class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
984
        public:
985
986
            AnyOf() {}
987
            AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
988
989
            AnyOf& add( Matcher<ExpressionT> const& matcher ) {
990
                m_matchers.push_back( matcher.clone() );
991
                return *this;
992
            }
993
            virtual bool match( ExpressionT const& expr ) const
994
            {
995
                for( std::size_t i = 0; i < m_matchers.size(); ++i )
996
                    if( m_matchers[i]->match( expr ) )
997
                        return true;
998
                return false;
999
            }
1000
            virtual std::string toString() const {
1001
                std::ostringstream oss;
1002
                oss << "( ";
1003
                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1004
                    if( i != 0 )
1005
                        oss << " or ";
1006
                    oss << m_matchers[i]->toString();
1007
                }
1008
                oss << " )";
1009
                return oss.str();
1010
            }
1011
1012
            AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
1013
                AnyOf anyOfExpr( *this );
1014
                anyOfExpr.add( other );
1015
                return anyOfExpr;
1016
            }
1017
1018
        private:
1019
            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
1020
        };
1021
1022
    } // namespace Generic
1023
1024
    template<typename ExpressionT>
1025
    Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
1026
        Generic::AllOf<ExpressionT> allOfExpr;
1027
        allOfExpr.add( *this );
1028
        allOfExpr.add( other );
1029
        return allOfExpr;
1030
    }
1031
1032
    template<typename ExpressionT>
1033
    Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
1034
        Generic::AnyOf<ExpressionT> anyOfExpr;
1035
        anyOfExpr.add( *this );
1036
        anyOfExpr.add( other );
1037
        return anyOfExpr;
1038
    }
1039
1040
    template<typename ExpressionT>
1041
    Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
1042
        return Generic::Not<ExpressionT>( *this );
1043
    }
1044
1045
    namespace StdString {
1046
1047
        inline std::string makeString( std::string const& str ) { return str; }
1048
        inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
1049
1050
        struct CasedString
1051
        {
1052
            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
1053
            :   m_caseSensitivity( caseSensitivity ),
1054
                m_str( adjustString( str ) )
1055
            {}
1056
            std::string adjustString( std::string const& str ) const {
1057
                return m_caseSensitivity == CaseSensitive::No
1058
                    ? toLower( str )
1059
                    : str;
1060
1061
            }
1062
            std::string toStringSuffix() const
1063
            {
1064
                return m_caseSensitivity == CaseSensitive::No
1065
                    ? " (case insensitive)"
1066
                    : "";
1067
            }
1068
            CaseSensitive::Choice m_caseSensitivity;
1069
            std::string m_str;
1070
        };
1071
1072
        struct Equals : MatcherImpl<Equals, std::string> {
1073
            Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1074
            :   m_data( str, caseSensitivity )
1075
            {}
1076
            Equals( Equals const& other ) : m_data( other.m_data ){}
1077
1078
            virtual ~Equals();
1079
1080
            virtual bool match( std::string const& expr ) const {
1081
                return m_data.m_str == m_data.adjustString( expr );;
1082
            }
1083
            virtual std::string toString() const {
1084
                return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1085
            }
1086
1087
            CasedString m_data;
1088
        };
1089
1090
        struct Contains : MatcherImpl<Contains, std::string> {
1091
            Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1092
            : m_data( substr, caseSensitivity ){}
1093
            Contains( Contains const& other ) : m_data( other.m_data ){}
1094
1095
            virtual ~Contains();
1096
1097
            virtual bool match( std::string const& expr ) const {
1098
                return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
1099
            }
1100
            virtual std::string toString() const {
1101
                return "contains: \"" + m_data.m_str  + "\"" + m_data.toStringSuffix();
1102
            }
1103
1104
            CasedString m_data;
1105
        };
1106
1107
        struct StartsWith : MatcherImpl<StartsWith, std::string> {
1108
            StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1109
            : m_data( substr, caseSensitivity ){}
1110
1111
            StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
1112
1113
            virtual ~StartsWith();
1114
1115
            virtual bool match( std::string const& expr ) const {
1116
                return startsWith( m_data.adjustString( expr ), m_data.m_str );
1117
            }
1118
            virtual std::string toString() const {
1119
                return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1120
            }
1121
1122
            CasedString m_data;
1123
        };
1124
1125
        struct EndsWith : MatcherImpl<EndsWith, std::string> {
1126
            EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1127
            : m_data( substr, caseSensitivity ){}
1128
            EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
1129
1130
            virtual ~EndsWith();
1131
1132
            virtual bool match( std::string const& expr ) const {
1133
                return endsWith( m_data.adjustString( expr ), m_data.m_str );
1134
            }
1135
            virtual std::string toString() const {
1136
                return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1137
            }
1138
1139
            CasedString m_data;
1140
        };
1141
    } // namespace StdString
1142
    } // namespace Impl
1143
1144
    // The following functions create the actual matcher objects.
1145
    // This allows the types to be inferred
1146
    template<typename ExpressionT>
1147
    inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
1148
        return Impl::Generic::Not<ExpressionT>( m );
1149
    }
1150
1151
    template<typename ExpressionT>
1152
    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
1153
                                                    Impl::Matcher<ExpressionT> const& m2 ) {
1154
        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
1155
    }
1156
    template<typename ExpressionT>
1157
    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
1158
                                                    Impl::Matcher<ExpressionT> const& m2,
1159
                                                    Impl::Matcher<ExpressionT> const& m3 ) {
1160
        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
1161
    }
1162
    template<typename ExpressionT>
1163
    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
1164
                                                    Impl::Matcher<ExpressionT> const& m2 ) {
1165
        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
1166
    }
1167
    template<typename ExpressionT>
1168
    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
1169
                                                    Impl::Matcher<ExpressionT> const& m2,
1170
                                                    Impl::Matcher<ExpressionT> const& m3 ) {
1171
        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
1172
    }
1173
1174
    inline Impl::StdString::Equals      Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1175
        return Impl::StdString::Equals( str, caseSensitivity );
1176
    }
1177
    inline Impl::StdString::Equals      Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1178
        return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
1179
    }
1180
    inline Impl::StdString::Contains    Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1181
        return Impl::StdString::Contains( substr, caseSensitivity );
1182
    }
1183
    inline Impl::StdString::Contains    Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1184
        return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
1185
    }
1186
    inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {
1187
        return Impl::StdString::StartsWith( substr );
1188
    }
1189
    inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {
1190
        return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
1191
    }
1192
    inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {
1193
        return Impl::StdString::EndsWith( substr );
1194
    }
1195
    inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {
1196
        return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
1197
    }
1198
1199
} // namespace Matchers
1200
1201
using namespace Matchers;
1202
1203
} // namespace Catch
1204
1205
namespace Catch {
1206
1207
    struct TestFailureException{};
1208
1209
    template<typename T> class ExpressionLhs;
1210
1211
    struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1212
1213
1433002
    struct CopyableStream {
1214
1433002
        CopyableStream() {}
1215
        CopyableStream( CopyableStream const& other ) {
1216
            oss << other.oss.str();
1217
        }
1218
        CopyableStream& operator=( CopyableStream const& other ) {
1219
            oss.str("");
1220
            oss << other.oss.str();
1221
            return *this;
1222
        }
1223
        std::ostringstream oss;
1224
    };
1225
1226
2866004
    class ResultBuilder {
1227
    public:
1228
        ResultBuilder(  char const* macroName,
1229
                        SourceLineInfo const& lineInfo,
1230
                        char const* capturedExpression,
1231
                        ResultDisposition::Flags resultDisposition,
1232
                        char const* secondArg = "" );
1233
1234
        template<typename T>
1235
        ExpressionLhs<T const&> operator <= ( T const& operand );
1236
        ExpressionLhs<bool> operator <= ( bool value );
1237
1238
        template<typename T>
1239
        ResultBuilder& operator << ( T const& value ) {
1240
            m_stream.oss << value;
1241
            return *this;
1242
        }
1243
1244
        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1245
        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1246
1247
        ResultBuilder& setResultType( ResultWas::OfType result );
1248
        ResultBuilder& setResultType( bool result );
1249
        ResultBuilder& setLhs( std::string const& lhs );
1250
        ResultBuilder& setRhs( std::string const& rhs );
1251
        ResultBuilder& setOp( std::string const& op );
1252
1253
        void endExpression();
1254
1255
        std::string reconstructExpression() const;
1256
        AssertionResult build() const;
1257
1258
        void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
1259
        void captureResult( ResultWas::OfType resultType );
1260
        void captureExpression();
1261
        void captureExpectedException( std::string const& expectedMessage );
1262
        void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
1263
        void handleResult( AssertionResult const& result );
1264
        void react();
1265
        bool shouldDebugBreak() const;
1266
        bool allowThrows() const;
1267
1268
    private:
1269
        AssertionInfo m_assertionInfo;
1270
        AssertionResultData m_data;
1271
5732008
        struct ExprComponents {
1272
5732008
            ExprComponents() : testFalse( false ) {}
1273
            bool testFalse;
1274
            std::string lhs, rhs, op;
1275
        } m_exprComponents;
1276
        CopyableStream m_stream;
1277
1278
        bool m_shouldDebugBreak;
1279
        bool m_shouldThrow;
1280
    };
1281
1282
} // namespace Catch
1283
1284
// Include after due to circular dependency:
1285
// #included from: catch_expression_lhs.hpp
1286
#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
1287
1288
// #included from: catch_evaluate.hpp
1289
#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
1290
1291
#ifdef _MSC_VER
1292
#pragma warning(push)
1293
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1294
#endif
1295
1296
#include <cstddef>
1297
1298
namespace Catch {
1299
namespace Internal {
1300
1301
    enum Operator {
1302
        IsEqualTo,
1303
        IsNotEqualTo,
1304
        IsLessThan,
1305
        IsGreaterThan,
1306
        IsLessThanOrEqualTo,
1307
        IsGreaterThanOrEqualTo
1308
    };
1309
1310
    template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
1311
    template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
1312
    template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
1313
    template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
1314
    template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
1315
    template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
1316
    template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
1317
1318
    template<typename T>
1319
    inline T& opCast(T const& t) { return const_cast<T&>(t); }
1320
1321
// nullptr_t support based on pull request #154 from Konstantin Baumann
1322
#ifdef CATCH_CONFIG_CPP11_NULLPTR
1323
    inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1324
#endif // CATCH_CONFIG_CPP11_NULLPTR
1325
1326
    // So the compare overloads can be operator agnostic we convey the operator as a template
1327
    // enum, which is used to specialise an Evaluator for doing the comparison.
1328
    template<typename T1, typename T2, Operator Op>
1329
    class Evaluator{};
1330
1331
    template<typename T1, typename T2>
1332
    struct Evaluator<T1, T2, IsEqualTo> {
1333
        static bool evaluate( T1 const& lhs, T2 const& rhs) {
1334
1415882
            return bool( opCast( lhs ) ==  opCast( rhs ) );
1335
        }
1336
    };
1337
    template<typename T1, typename T2>
1338
    struct Evaluator<T1, T2, IsNotEqualTo> {
1339
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1340
10356
            return bool( opCast( lhs ) != opCast( rhs ) );
1341
        }
1342
    };
1343
    template<typename T1, typename T2>
1344
    struct Evaluator<T1, T2, IsLessThan> {
1345
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1346
4031
            return bool( opCast( lhs ) < opCast( rhs ) );
1347
        }
1348
    };
1349
    template<typename T1, typename T2>
1350
    struct Evaluator<T1, T2, IsGreaterThan> {
1351
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1352
2685
            return bool( opCast( lhs ) > opCast( rhs ) );
1353
        }
1354
    };
1355
    template<typename T1, typename T2>
1356
    struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
1357
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1358
22
            return bool( opCast( lhs ) >= opCast( rhs ) );
1359
        }
1360
    };
1361
    template<typename T1, typename T2>
1362
    struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
1363
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1364
4
            return bool( opCast( lhs ) <= opCast( rhs ) );
1365
        }
1366
    };
1367
1368
    template<Operator Op, typename T1, typename T2>
1369
    bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1370
642
        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1371
    }
1372
1373
    // This level of indirection allows us to specialise for integer types
1374
    // to avoid signed/ unsigned warnings
1375
1376
    // "base" overload
1377
    template<Operator Op, typename T1, typename T2>
1378
    bool compare( T1 const& lhs, T2 const& rhs ) {
1379
1421478
        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1380
    }
1381
1382
    // unsigned X to int
1383
    template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1384
133
        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1385
    }
1386
    template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1387
278
        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1388
    }
1389
    template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1390
144
        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1391
    }
1392
1393
    // unsigned X to long
1394
    template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1395
        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1396
    }
1397
    template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1398
        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1399
    }
1400
    template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1401
        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1402
    }
1403
1404
    // int to unsigned X
1405
    template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1406
60
        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1407
    }
1408
    template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1409
27
        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1410
    }
1411
    template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1412
        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1413
    }
1414
1415
    // long to unsigned X
1416
    template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1417
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1418
    }
1419
    template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1420
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1421
    }
1422
    template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1423
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1424
    }
1425
1426
    // pointer to long (when comparing against NULL)
1427
    template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1428
        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1429
    }
1430
    template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1431
        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1432
    }
1433
1434
    // pointer to int (when comparing against NULL)
1435
    template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1436
        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1437
    }
1438
    template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1439
        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1440
    }
1441
1442
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
1443
    // long long to unsigned X
1444
    template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
1445
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1446
    }
1447
    template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
1448
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1449
    }
1450
    template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
1451
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1452
    }
1453
    template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
1454
        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1455
    }
1456
1457
    // unsigned long long to X
1458
    template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
1459
        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1460
    }
1461
    template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
1462
        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1463
    }
1464
    template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
1465
        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1466
    }
1467
    template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
1468
        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1469
    }
1470
1471
    // pointer to long long (when comparing against NULL)
1472
    template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
1473
        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1474
    }
1475
    template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
1476
        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1477
    }
1478
#endif // CATCH_CONFIG_CPP11_LONG_LONG
1479
1480
#ifdef CATCH_CONFIG_CPP11_NULLPTR
1481
    // pointer to nullptr_t (when comparing against nullptr)
1482
    template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1483
30
        return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
1484
    }
1485
    template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1486
10365
        return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
1487
    }
1488
#endif // CATCH_CONFIG_CPP11_NULLPTR
1489
1490
} // end of namespace Internal
1491
} // end of namespace Catch
1492
1493
#ifdef _MSC_VER
1494
#pragma warning(pop)
1495
#endif
1496
1497
// #included from: catch_tostring.h
1498
#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1499
1500
#include <sstream>
1501
#include <iomanip>
1502
#include <limits>
1503
#include <vector>
1504
#include <cstddef>
1505
1506
#ifdef __OBJC__
1507
// #included from: catch_objc_arc.hpp
1508
#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1509
1510
#import <Foundation/Foundation.h>
1511
1512
#ifdef __has_feature
1513
#define CATCH_ARC_ENABLED __has_feature(objc_arc)
1514
#else
1515
#define CATCH_ARC_ENABLED 0
1516
#endif
1517
1518
void arcSafeRelease( NSObject* obj );
1519
id performOptionalSelector( id obj, SEL sel );
1520
1521
#if !CATCH_ARC_ENABLED
1522
inline void arcSafeRelease( NSObject* obj ) {
1523
    [obj release];
1524
}
1525
inline id performOptionalSelector( id obj, SEL sel ) {
1526
    if( [obj respondsToSelector: sel] )
1527
        return [obj performSelector: sel];
1528
    return nil;
1529
}
1530
#define CATCH_UNSAFE_UNRETAINED
1531
#define CATCH_ARC_STRONG
1532
#else
1533
inline void arcSafeRelease( NSObject* ){}
1534
inline id performOptionalSelector( id obj, SEL sel ) {
1535
#ifdef __clang__
1536
#pragma clang diagnostic push
1537
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1538
#endif
1539
    if( [obj respondsToSelector: sel] )
1540
        return [obj performSelector: sel];
1541
#ifdef __clang__
1542
#pragma clang diagnostic pop
1543
#endif
1544
    return nil;
1545
}
1546
#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1547
#define CATCH_ARC_STRONG __strong
1548
#endif
1549
1550
#endif
1551
1552
#ifdef CATCH_CONFIG_CPP11_TUPLE
1553
#include <tuple>
1554
#endif
1555
1556
#ifdef CATCH_CONFIG_CPP11_IS_ENUM
1557
#include <type_traits>
1558
#endif
1559
1560
namespace Catch {
1561
1562
// Why we're here.
1563
template<typename T>
1564
std::string toString( T const& value );
1565
1566
// Built in overloads
1567
1568
std::string toString( std::string const& value );
1569
std::string toString( std::wstring const& value );
1570
std::string toString( const char* const value );
1571
std::string toString( char* const value );
1572
std::string toString( const wchar_t* const value );
1573
std::string toString( wchar_t* const value );
1574
std::string toString( int value );
1575
std::string toString( unsigned long value );
1576
std::string toString( unsigned int value );
1577
std::string toString( const double value );
1578
std::string toString( const float value );
1579
std::string toString( bool value );
1580
std::string toString( char value );
1581
std::string toString( signed char value );
1582
std::string toString( unsigned char value );
1583
1584
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
1585
std::string toString( long long value );
1586
std::string toString( unsigned long long value );
1587
#endif
1588
1589
#ifdef CATCH_CONFIG_CPP11_NULLPTR
1590
std::string toString( std::nullptr_t );
1591
#endif
1592
1593
#ifdef __OBJC__
1594
    std::string toString( NSString const * const& nsstring );
1595
    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
1596
    std::string toString( NSObject* const& nsObject );
1597
#endif
1598
1599
namespace Detail {
1600
1601
    extern const std::string unprintableString;
1602
1603
    struct BorgType {
1604
        template<typename T> BorgType( T const& );
1605
    };
1606
1607
    struct TrueType { char sizer[1]; };
1608
    struct FalseType { char sizer[2]; };
1609
1610
    TrueType& testStreamable( std::ostream& );
1611
    FalseType testStreamable( FalseType );
1612
1613
    FalseType operator<<( std::ostream const&, BorgType const& );
1614
1615
    template<typename T>
1616
    struct IsStreamInsertable {
1617
        static std::ostream &s;
1618
        static T  const&t;
1619
        enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1620
    };
1621
1622
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1623
    template<typename T,
1624
             bool IsEnum = std::is_enum<T>::value
1625
             >
1626
    struct EnumStringMaker
1627
    {
1628
74
        static std::string convert( T const& ) { return unprintableString; }
1629
    };
1630
1631
    template<typename T>
1632
    struct EnumStringMaker<T,true>
1633
    {
1634
        static std::string convert( T const& v )
1635
        {
1636
            return ::Catch::toString(
1637
                static_cast<typename std::underlying_type<T>::type>(v)
1638


4486
                );
1639
        }
1640
    };
1641
#endif
1642
    template<bool C>
1643
    struct StringMakerBase {
1644
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1645
        template<typename T>
1646
        static std::string convert( T const& v )
1647
        {
1648
4560
            return EnumStringMaker<T>::convert( v );
1649
        }
1650
#else
1651
        template<typename T>
1652
        static std::string convert( T const& ) { return unprintableString; }
1653
#endif
1654
    };
1655
1656
    template<>
1657
    struct StringMakerBase<true> {
1658
        template<typename T>
1659
926880
        static std::string convert( T const& _value ) {
1660
1853760
            std::ostringstream oss;
1661
1853760
            oss << _value;
1662
1853760
            return oss.str();
1663
        }
1664
    };
1665
1666
    std::string rawMemoryToString( const void *object, std::size_t size );
1667
1668
    template<typename T>
1669
    inline std::string rawMemoryToString( const T& object ) {
1670
10579
      return rawMemoryToString( &object, sizeof(object) );
1671
    }
1672
1673
} // end namespace Detail
1674
1675
template<typename T>
1676
struct StringMaker :
1677
    Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1678
1679
template<typename T>
1680
struct StringMaker<T*> {
1681
    template<typename U>
1682
10686
    static std::string convert( U* p ) {
1683


10686
        if( !p )
1684
287
            return "NULL";
1685
        else
1686
            return Detail::rawMemoryToString( p );
1687
    }
1688
};
1689
1690
template<typename R, typename C>
1691
struct StringMaker<R C::*> {
1692
    static std::string convert( R C::* p ) {
1693
        if( !p )
1694
            return "NULL";
1695
        else
1696
            return Detail::rawMemoryToString( p );
1697
    }
1698
};
1699
1700
namespace Detail {
1701
    template<typename InputIterator>
1702
    std::string rangeToString( InputIterator first, InputIterator last );
1703
}
1704
1705
//template<typename T, typename Allocator>
1706
//struct StringMaker<std::vector<T, Allocator> > {
1707
//    static std::string convert( std::vector<T,Allocator> const& v ) {
1708
//        return Detail::rangeToString( v.begin(), v.end() );
1709
//    }
1710
//};
1711
1712
template<typename T, typename Allocator>
1713
std::string toString( std::vector<T,Allocator> const& v ) {
1714
    return Detail::rangeToString( v.begin(), v.end() );
1715
}
1716
1717
#ifdef CATCH_CONFIG_CPP11_TUPLE
1718
1719
// toString for tuples
1720
namespace TupleDetail {
1721
  template<
1722
      typename Tuple,
1723
      std::size_t N = 0,
1724
      bool = (N < std::tuple_size<Tuple>::value)
1725
      >
1726
  struct ElementPrinter {
1727
      static void print( const Tuple& tuple, std::ostream& os )
1728
      {
1729
          os << ( N ? ", " : " " )
1730
             << Catch::toString(std::get<N>(tuple));
1731
          ElementPrinter<Tuple,N+1>::print(tuple,os);
1732
      }
1733
  };
1734
1735
  template<
1736
      typename Tuple,
1737
      std::size_t N
1738
      >
1739
  struct ElementPrinter<Tuple,N,false> {
1740
      static void print( const Tuple&, std::ostream& ) {}
1741
  };
1742
1743
}
1744
1745
template<typename ...Types>
1746
struct StringMaker<std::tuple<Types...>> {
1747
1748
    static std::string convert( const std::tuple<Types...>& tuple )
1749
    {
1750
        std::ostringstream os;
1751
        os << '{';
1752
        TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1753
        os << " }";
1754
        return os.str();
1755
    }
1756
};
1757
#endif // CATCH_CONFIG_CPP11_TUPLE
1758
1759
namespace Detail {
1760
    template<typename T>
1761
    std::string makeString( T const& value ) {
1762
926654
        return StringMaker<T>::convert( value );
1763
    }
1764
} // end namespace Detail
1765
1766
/// \brief converts any type to a string
1767
///
1768
/// The default template forwards on to ostringstream - except when an
1769
/// ostringstream overload does not exist - in which case it attempts to detect
1770
/// that and writes {?}.
1771
/// Overload (not specialise) this template for custom typs that you don't want
1772
/// to provide an ostream overload for.
1773
template<typename T>
1774
std::string toString( T const& value ) {
1775



15472
    return StringMaker<T>::convert( value );
1776
}
1777
1778
    namespace Detail {
1779
    template<typename InputIterator>
1780
    std::string rangeToString( InputIterator first, InputIterator last ) {
1781
        std::ostringstream oss;
1782
        oss << "{ ";
1783
        if( first != last ) {
1784
            oss << Catch::toString( *first );
1785
            for( ++first ; first != last ; ++first )
1786
                oss << ", " << Catch::toString( *first );
1787
        }
1788
        oss << " }";
1789
        return oss.str();
1790
    }
1791
}
1792
1793
} // end namespace Catch
1794
1795
namespace Catch {
1796
1797
// Wraps the LHS of an expression and captures the operator and RHS (if any) -
1798
// wrapping them all in a ResultBuilder object
1799
template<typename T>
1800
class ExpressionLhs {
1801
    ExpressionLhs& operator = ( ExpressionLhs const& );
1802
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1803
    ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
1804
#  endif
1805
1806
public:
1807
81028
    ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
1808
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1809
    ExpressionLhs( ExpressionLhs const& ) = default;
1810
    ExpressionLhs( ExpressionLhs && )     = default;
1811
#  endif
1812
1813
    template<typename RhsT>
1814
    ResultBuilder& operator == ( RhsT const& rhs ) {
1815
































































































































































































































































1334796
        return captureExpression<Internal::IsEqualTo>( rhs );
1816
    }
1817
1818
    template<typename RhsT>
1819
    ResultBuilder& operator != ( RhsT const& rhs ) {
1820

































10326
        return captureExpression<Internal::IsNotEqualTo>( rhs );
1821
    }
1822
1823
    template<typename RhsT>
1824
    ResultBuilder& operator < ( RhsT const& rhs ) {
1825





4031
        return captureExpression<Internal::IsLessThan>( rhs );
1826
    }
1827
1828
    template<typename RhsT>
1829
    ResultBuilder& operator > ( RhsT const& rhs ) {
1830


2685
        return captureExpression<Internal::IsGreaterThan>( rhs );
1831
    }
1832
1833
    template<typename RhsT>
1834
    ResultBuilder& operator <= ( RhsT const& rhs ) {
1835


4
        return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1836
    }
1837
1838
    template<typename RhsT>
1839
    ResultBuilder& operator >= ( RhsT const& rhs ) {
1840










22
        return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1841
    }
1842
1843
    ResultBuilder& operator == ( bool rhs ) {
1844
































































80637
        return captureExpression<Internal::IsEqualTo>( rhs );
1845
    }
1846
1847
    ResultBuilder& operator != ( bool rhs ) {
1848
        return captureExpression<Internal::IsNotEqualTo>( rhs );
1849
    }
1850
1851
469
    void endExpression() {
1852
469
        bool value = m_lhs ? true : false;
1853

938
        m_rb
1854

1407
            .setLhs( Catch::toString( value ) )
1855

938
            .setResultType( value )
1856
            .endExpression();
1857
469
    }
1858
1859
    // Only simple binary expressions are allowed on the LHS.
1860
    // If more complex compositions are required then place the sub expression in parentheses
1861
    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1862
    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1863
    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1864
    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1865
    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1866
    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1867
1868
private:
1869
    template<Internal::Operator Op, typename RhsT>
1870
1432502
    ResultBuilder& captureExpression( RhsT const& rhs ) {
1871
1432502
        return m_rb
1872
1525593
            .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1873


































4284506
            .setLhs( Catch::toString( m_lhs ) )
1874




































































4297662
            .setRhs( Catch::toString( rhs ) )
1875












































































































8595082
            .setOp( Internal::OperatorTraits<Op>::getName() );
1876
    }
1877
1878
private:
1879
    ResultBuilder& m_rb;
1880
    T m_lhs;
1881
};
1882
1883
} // end namespace Catch
1884
1885
1886
namespace Catch {
1887
1888
    template<typename T>
1889
    inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
1890
1351902
        return ExpressionLhs<T const&>( *this, operand );
1891
    }
1892
1893
    inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
1894
162096
        return ExpressionLhs<bool>( *this, value );
1895
    }
1896
1897
} // namespace Catch
1898
1899
// #included from: catch_message.h
1900
#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1901
1902
#include <string>
1903
1904
namespace Catch {
1905
1906
    struct MessageInfo {
1907
        MessageInfo(    std::string const& _macroName,
1908
                        SourceLineInfo const& _lineInfo,
1909
                        ResultWas::OfType _type );
1910
1911
        std::string macroName;
1912
        SourceLineInfo lineInfo;
1913
        ResultWas::OfType type;
1914
        std::string message;
1915
        unsigned int sequence;
1916
1917
        bool operator == ( MessageInfo const& other ) const {
1918
            return sequence == other.sequence;
1919
        }
1920
        bool operator < ( MessageInfo const& other ) const {
1921
            return sequence < other.sequence;
1922
        }
1923
    private:
1924
        static unsigned int globalCount;
1925
    };
1926
1927
    struct MessageBuilder {
1928
        MessageBuilder( std::string const& macroName,
1929
                        SourceLineInfo const& lineInfo,
1930
                        ResultWas::OfType type )
1931
        : m_info( macroName, lineInfo, type )
1932
        {}
1933
1934
        template<typename T>
1935
        MessageBuilder& operator << ( T const& value ) {
1936
            m_stream << value;
1937
            return *this;
1938
        }
1939
1940
        MessageInfo m_info;
1941
        std::ostringstream m_stream;
1942
    };
1943
1944
    class ScopedMessage {
1945
    public:
1946
        ScopedMessage( MessageBuilder const& builder );
1947
        ScopedMessage( ScopedMessage const& other );
1948
        ~ScopedMessage();
1949
1950
        MessageInfo m_info;
1951
    };
1952
1953
} // end namespace Catch
1954
1955
// #included from: catch_interfaces_capture.h
1956
#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1957
1958
#include <string>
1959
1960
namespace Catch {
1961
1962
    class TestCase;
1963
    class AssertionResult;
1964
    struct AssertionInfo;
1965
    struct SectionInfo;
1966
    struct SectionEndInfo;
1967
    struct MessageInfo;
1968
    class ScopedMessageBuilder;
1969
    struct Counts;
1970
1971
    struct IResultCapture {
1972
1973
        virtual ~IResultCapture();
1974
1975
        virtual void assertionEnded( AssertionResult const& result ) = 0;
1976
        virtual bool sectionStarted(    SectionInfo const& sectionInfo,
1977
                                        Counts& assertions ) = 0;
1978
        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
1979
        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
1980
        virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1981
        virtual void popScopedMessage( MessageInfo const& message ) = 0;
1982
1983
        virtual std::string getCurrentTestName() const = 0;
1984
        virtual const AssertionResult* getLastResult() const = 0;
1985
1986
        virtual void handleFatalErrorCondition( std::string const& message ) = 0;
1987
    };
1988
1989
    IResultCapture& getResultCapture();
1990
}
1991
1992
// #included from: catch_debugger.h
1993
#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
1994
1995
// #included from: catch_platform.h
1996
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1997
1998
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1999
#define CATCH_PLATFORM_MAC
2000
#elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
2001
#define CATCH_PLATFORM_IPHONE
2002
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
2003
#define CATCH_PLATFORM_WINDOWS
2004
#endif
2005
2006
#include <string>
2007
2008
namespace Catch{
2009
2010
    bool isDebuggerActive();
2011
    void writeToDebugConsole( std::string const& text );
2012
}
2013
2014
#ifdef CATCH_PLATFORM_MAC
2015
2016
    // The following code snippet based on:
2017
    // http://cocoawithlove.com/2008/03/break-into-debugger.html
2018
    #ifdef DEBUG
2019
        #if defined(__ppc64__) || defined(__ppc__)
2020
            #define CATCH_BREAK_INTO_DEBUGGER() \
2021
                if( Catch::isDebuggerActive() ) { \
2022
                    __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
2023
                    : : : "memory","r0","r3","r4" ); \
2024
                }
2025
        #else
2026
            #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
2027
        #endif
2028
    #endif
2029
2030
#elif defined(_MSC_VER)
2031
    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
2032
#elif defined(__MINGW32__)
2033
    extern "C" __declspec(dllimport) void __stdcall DebugBreak();
2034
    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
2035
#endif
2036
2037
#ifndef CATCH_BREAK_INTO_DEBUGGER
2038
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
2039
#endif
2040
2041
// #included from: catch_interfaces_runner.h
2042
#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
2043
2044
namespace Catch {
2045
    class TestCase;
2046
2047
    struct IRunner {
2048
        virtual ~IRunner();
2049
        virtual bool aborting() const = 0;
2050
    };
2051
}
2052
2053
///////////////////////////////////////////////////////////////////////////////
2054
// In the event of a failure works out if the debugger needs to be invoked
2055
// and/or an exception thrown and takes appropriate action.
2056
// This needs to be done as a macro so the debugger will stop in the user
2057
// source code rather than in Catch library code
2058
#define INTERNAL_CATCH_REACT( resultBuilder ) \
2059
    if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
2060
    resultBuilder.react();
2061
2062
///////////////////////////////////////////////////////////////////////////////
2063
#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
2064
    do { \
2065
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2066
        try { \
2067
            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2068
            ( __catchResult <= expr ).endExpression(); \
2069
        } \
2070
        catch( ... ) { \
2071
            __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
2072
        } \
2073
        INTERNAL_CATCH_REACT( __catchResult ) \
2074
    } while( Catch::isTrue( false && static_cast<bool>(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
2075
2076
///////////////////////////////////////////////////////////////////////////////
2077
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
2078
    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2079
    if( Catch::getResultCapture().getLastResult()->succeeded() )
2080
2081
///////////////////////////////////////////////////////////////////////////////
2082
#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
2083
    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2084
    if( !Catch::getResultCapture().getLastResult()->succeeded() )
2085
2086
///////////////////////////////////////////////////////////////////////////////
2087
#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
2088
    do { \
2089
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2090
        try { \
2091
            expr; \
2092
            __catchResult.captureResult( Catch::ResultWas::Ok ); \
2093
        } \
2094
        catch( ... ) { \
2095
            __catchResult.useActiveException( resultDisposition ); \
2096
        } \
2097
        INTERNAL_CATCH_REACT( __catchResult ) \
2098
    } while( Catch::alwaysFalse() )
2099
2100
///////////////////////////////////////////////////////////////////////////////
2101
#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
2102
    do { \
2103
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
2104
        if( __catchResult.allowThrows() ) \
2105
            try { \
2106
                expr; \
2107
                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2108
            } \
2109
            catch( ... ) { \
2110
                __catchResult.captureExpectedException( matcher ); \
2111
            } \
2112
        else \
2113
            __catchResult.captureResult( Catch::ResultWas::Ok ); \
2114
        INTERNAL_CATCH_REACT( __catchResult ) \
2115
    } while( Catch::alwaysFalse() )
2116
2117
///////////////////////////////////////////////////////////////////////////////
2118
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
2119
    do { \
2120
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2121
        if( __catchResult.allowThrows() ) \
2122
            try { \
2123
                expr; \
2124
                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2125
            } \
2126
            catch( exceptionType ) { \
2127
                __catchResult.captureResult( Catch::ResultWas::Ok ); \
2128
            } \
2129
            catch( ... ) { \
2130
                __catchResult.useActiveException( resultDisposition ); \
2131
            } \
2132
        else \
2133
            __catchResult.captureResult( Catch::ResultWas::Ok ); \
2134
        INTERNAL_CATCH_REACT( __catchResult ) \
2135
    } while( Catch::alwaysFalse() )
2136
2137
///////////////////////////////////////////////////////////////////////////////
2138
#ifdef CATCH_CONFIG_VARIADIC_MACROS
2139
    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
2140
        do { \
2141
            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2142
            __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
2143
            __catchResult.captureResult( messageType ); \
2144
            INTERNAL_CATCH_REACT( __catchResult ) \
2145
        } while( Catch::alwaysFalse() )
2146
#else
2147
    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
2148
        do { \
2149
            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2150
            __catchResult << log + ::Catch::StreamEndStop(); \
2151
            __catchResult.captureResult( messageType ); \
2152
            INTERNAL_CATCH_REACT( __catchResult ) \
2153
        } while( Catch::alwaysFalse() )
2154
#endif
2155
2156
///////////////////////////////////////////////////////////////////////////////
2157
#define INTERNAL_CATCH_INFO( log, macroName ) \
2158
    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2159
2160
///////////////////////////////////////////////////////////////////////////////
2161
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
2162
    do { \
2163
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
2164
        try { \
2165
            std::string matcherAsString = (matcher).toString(); \
2166
            __catchResult \
2167
                .setLhs( Catch::toString( arg ) ) \
2168
                .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
2169
                .setOp( "matches" ) \
2170
                .setResultType( (matcher).match( arg ) ); \
2171
            __catchResult.captureExpression(); \
2172
        } catch( ... ) { \
2173
            __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
2174
        } \
2175
        INTERNAL_CATCH_REACT( __catchResult ) \
2176
    } while( Catch::alwaysFalse() )
2177
2178
// #included from: internal/catch_section.h
2179
#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
2180
2181
// #included from: catch_section_info.h
2182
#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
2183
2184
// #included from: catch_totals.hpp
2185
#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
2186
2187
#include <cstddef>
2188
2189
namespace Catch {
2190
2191
    struct Counts {
2192
10352
        Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2193
2194
        Counts operator - ( Counts const& other ) const {
2195
1957
            Counts diff;
2196
1957
            diff.passed = passed - other.passed;
2197
1957
            diff.failed = failed - other.failed;
2198
1957
            diff.failedButOk = failedButOk - other.failedButOk;
2199
            return diff;
2200
        }
2201
        Counts& operator += ( Counts const& other ) {
2202
1185
            passed += other.passed;
2203
1185
            failed += other.failed;
2204
1185
            failedButOk += other.failedButOk;
2205
            return *this;
2206
        }
2207
2208
        std::size_t total() const {
2209
1170
            return passed + failed + failedButOk;
2210
        }
2211
        bool allPassed() const {
2212


2
            return failed == 0 && failedButOk == 0;
2213
        }
2214
        bool allOk() const {
2215
            return failed == 0;
2216
        }
2217
2218
        std::size_t passed;
2219
        std::size_t failed;
2220
        std::size_t failedButOk;
2221
    };
2222
2223
1191
    struct Totals {
2224
2225
        Totals operator - ( Totals const& other ) const {
2226
395
            Totals diff;
2227
790
            diff.assertions = assertions - other.assertions;
2228
790
            diff.testCases = testCases - other.testCases;
2229
            return diff;
2230
        }
2231
2232
395
        Totals delta( Totals const& prevTotals ) const {
2233
395
            Totals diff = *this - prevTotals;
2234
395
            if( diff.assertions.failed > 0 )
2235
                ++diff.testCases.failed;
2236
395
            else if( diff.assertions.failedButOk > 0 )
2237
                ++diff.testCases.failedButOk;
2238
            else
2239
395
                ++diff.testCases.passed;
2240
395
            return diff;
2241
        }
2242
2243
        Totals& operator += ( Totals const& other ) {
2244
790
            assertions += other.assertions;
2245
790
            testCases += other.testCases;
2246
            return *this;
2247
        }
2248
2249
        Counts assertions;
2250
        Counts testCases;
2251
    };
2252
}
2253
2254
namespace Catch {
2255
2256
125684
    struct SectionInfo {
2257
        SectionInfo
2258
            (   SourceLineInfo const& _lineInfo,
2259
                std::string const& _name,
2260
                std::string const& _description = std::string() );
2261
2262
        std::string name;
2263
        std::string description;
2264
        SourceLineInfo lineInfo;
2265
    };
2266
2267
411
    struct SectionEndInfo {
2268
        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
2269
411
        : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2270
        {}
2271
2272
        SectionInfo sectionInfo;
2273
        Counts prevAssertions;
2274
        double durationInSeconds;
2275
    };
2276
2277
} // end namespace Catch
2278
2279
// #included from: catch_timer.h
2280
#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2281
2282
#ifdef CATCH_PLATFORM_WINDOWS
2283
typedef unsigned long long uint64_t;
2284
#else
2285
#include <stdint.h>
2286
#endif
2287
2288
namespace Catch {
2289
2290
    class Timer {
2291
    public:
2292
9147
        Timer() : m_ticks( 0 ) {}
2293
        void start();
2294
        unsigned int getElapsedMicroseconds() const;
2295
        unsigned int getElapsedMilliseconds() const;
2296
        double getElapsedSeconds() const;
2297
2298
    private:
2299
        uint64_t m_ticks;
2300
    };
2301
2302
} // namespace Catch
2303
2304
#include <string>
2305
2306
namespace Catch {
2307
2308
    class Section : NonCopyable {
2309
    public:
2310
        Section( SectionInfo const& info );
2311
        ~Section();
2312
2313
        // This indicates whether the section should be executed or not
2314
        operator bool() const;
2315
2316
    private:
2317
        SectionInfo m_info;
2318
2319
        std::string m_name;
2320
        Counts m_assertions;
2321
        bool m_sectionIncluded;
2322
        Timer m_timer;
2323
    };
2324
2325
} // end namespace Catch
2326
2327
#ifdef CATCH_CONFIG_VARIADIC_MACROS
2328
    #define INTERNAL_CATCH_SECTION( ... ) \
2329
        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2330
#else
2331
    #define INTERNAL_CATCH_SECTION( name, desc ) \
2332
        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
2333
#endif
2334
2335
// #included from: internal/catch_generators.hpp
2336
#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2337
2338
#include <iterator>
2339
#include <vector>
2340
#include <string>
2341
#include <stdlib.h>
2342
2343
namespace Catch {
2344
2345
template<typename T>
2346
struct IGenerator {
2347
    virtual ~IGenerator() {}
2348
    virtual T getValue( std::size_t index ) const = 0;
2349
    virtual std::size_t size () const = 0;
2350
};
2351
2352
template<typename T>
2353
class BetweenGenerator : public IGenerator<T> {
2354
public:
2355
    BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
2356
2357
    virtual T getValue( std::size_t index ) const {
2358
        return m_from+static_cast<int>( index );
2359
    }
2360
2361
    virtual std::size_t size() const {
2362
        return static_cast<std::size_t>( 1+m_to-m_from );
2363
    }
2364
2365
private:
2366
2367
    T m_from;
2368
    T m_to;
2369
};
2370
2371
template<typename T>
2372
class ValuesGenerator : public IGenerator<T> {
2373
public:
2374
    ValuesGenerator(){}
2375
2376
    void add( T value ) {
2377
        m_values.push_back( value );
2378
    }
2379
2380
    virtual T getValue( std::size_t index ) const {
2381
        return m_values[index];
2382
    }
2383
2384
    virtual std::size_t size() const {
2385
        return m_values.size();
2386
    }
2387
2388
private:
2389
    std::vector<T> m_values;
2390
};
2391
2392
template<typename T>
2393
class CompositeGenerator {
2394
public:
2395
    CompositeGenerator() : m_totalSize( 0 ) {}
2396
2397
    // *** Move semantics, similar to auto_ptr ***
2398
    CompositeGenerator( CompositeGenerator& other )
2399
    :   m_fileInfo( other.m_fileInfo ),
2400
        m_totalSize( 0 )
2401
    {
2402
        move( other );
2403
    }
2404
2405
    CompositeGenerator& setFileInfo( const char* fileInfo ) {
2406
        m_fileInfo = fileInfo;
2407
        return *this;
2408
    }
2409
2410
    ~CompositeGenerator() {
2411
        deleteAll( m_composed );
2412
    }
2413
2414
    operator T () const {
2415
        size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
2416
2417
        typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2418
        typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2419
        for( size_t index = 0; it != itEnd; ++it )
2420
        {
2421
            const IGenerator<T>* generator = *it;
2422
            if( overallIndex >= index && overallIndex < index + generator->size() )
2423
            {
2424
                return generator->getValue( overallIndex-index );
2425
            }
2426
            index += generator->size();
2427
        }
2428
        CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
2429
        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
2430
    }
2431
2432
    void add( const IGenerator<T>* generator ) {
2433
        m_totalSize += generator->size();
2434
        m_composed.push_back( generator );
2435
    }
2436
2437
    CompositeGenerator& then( CompositeGenerator& other ) {
2438
        move( other );
2439
        return *this;
2440
    }
2441
2442
    CompositeGenerator& then( T value ) {
2443
        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2444
        valuesGen->add( value );
2445
        add( valuesGen );
2446
        return *this;
2447
    }
2448
2449
private:
2450
2451
    void move( CompositeGenerator& other ) {
2452
        std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
2453
        m_totalSize += other.m_totalSize;
2454
        other.m_composed.clear();
2455
    }
2456
2457
    std::vector<const IGenerator<T>*> m_composed;
2458
    std::string m_fileInfo;
2459
    size_t m_totalSize;
2460
};
2461
2462
namespace Generators
2463
{
2464
    template<typename T>
2465
    CompositeGenerator<T> between( T from, T to ) {
2466
        CompositeGenerator<T> generators;
2467
        generators.add( new BetweenGenerator<T>( from, to ) );
2468
        return generators;
2469
    }
2470
2471
    template<typename T>
2472
    CompositeGenerator<T> values( T val1, T val2 ) {
2473
        CompositeGenerator<T> generators;
2474
        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2475
        valuesGen->add( val1 );
2476
        valuesGen->add( val2 );
2477
        generators.add( valuesGen );
2478
        return generators;
2479
    }
2480
2481
    template<typename T>
2482
    CompositeGenerator<T> values( T val1, T val2, T val3 ){
2483
        CompositeGenerator<T> generators;
2484
        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2485
        valuesGen->add( val1 );
2486
        valuesGen->add( val2 );
2487
        valuesGen->add( val3 );
2488
        generators.add( valuesGen );
2489
        return generators;
2490
    }
2491
2492
    template<typename T>
2493
    CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
2494
        CompositeGenerator<T> generators;
2495
        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2496
        valuesGen->add( val1 );
2497
        valuesGen->add( val2 );
2498
        valuesGen->add( val3 );
2499
        valuesGen->add( val4 );
2500
        generators.add( valuesGen );
2501
        return generators;
2502
    }
2503
2504
} // end namespace Generators
2505
2506
using namespace Generators;
2507
2508
} // end namespace Catch
2509
2510
#define INTERNAL_CATCH_LINESTR2( line ) #line
2511
#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2512
2513
#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2514
2515
// #included from: internal/catch_interfaces_exception.h
2516
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2517
2518
#include <string>
2519
#include <vector>
2520
2521
// #included from: catch_interfaces_registry_hub.h
2522
#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2523
2524
#include <string>
2525
2526
namespace Catch {
2527
2528
    class TestCase;
2529
    struct ITestCaseRegistry;
2530
    struct IExceptionTranslatorRegistry;
2531
    struct IExceptionTranslator;
2532
    struct IReporterRegistry;
2533
    struct IReporterFactory;
2534
2535
    struct IRegistryHub {
2536
        virtual ~IRegistryHub();
2537
2538
        virtual IReporterRegistry const& getReporterRegistry() const = 0;
2539
        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2540
        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2541
    };
2542
2543
    struct IMutableRegistryHub {
2544
        virtual ~IMutableRegistryHub();
2545
        virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
2546
        virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
2547
        virtual void registerTest( TestCase const& testInfo ) = 0;
2548
        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2549
    };
2550
2551
    IRegistryHub& getRegistryHub();
2552
    IMutableRegistryHub& getMutableRegistryHub();
2553
    void cleanUp();
2554
    std::string translateActiveException();
2555
2556
}
2557
2558
namespace Catch {
2559
2560
    typedef std::string(*exceptionTranslateFunction)();
2561
2562
    struct IExceptionTranslator;
2563
    typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
2564
2565
    struct IExceptionTranslator {
2566
        virtual ~IExceptionTranslator();
2567
        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2568
    };
2569
2570
    struct IExceptionTranslatorRegistry {
2571
        virtual ~IExceptionTranslatorRegistry();
2572
2573
        virtual std::string translateActiveException() const = 0;
2574
    };
2575
2576
    class ExceptionTranslatorRegistrar {
2577
        template<typename T>
2578
        class ExceptionTranslator : public IExceptionTranslator {
2579
        public:
2580
2581
            ExceptionTranslator( std::string(*translateFunction)( T& ) )
2582
            : m_translateFunction( translateFunction )
2583
            {}
2584
2585
            virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
2586
                try {
2587
                    if( it == itEnd )
2588
                        throw;
2589
                    else
2590
                        return (*it)->translate( it+1, itEnd );
2591
                }
2592
                catch( T& ex ) {
2593
                    return m_translateFunction( ex );
2594
                }
2595
            }
2596
2597
        protected:
2598
            std::string(*m_translateFunction)( T& );
2599
        };
2600
2601
    public:
2602
        template<typename T>
2603
        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2604
            getMutableRegistryHub().registerTranslator
2605
                ( new ExceptionTranslator<T>( translateFunction ) );
2606
        }
2607
    };
2608
}
2609
2610
///////////////////////////////////////////////////////////////////////////////
2611
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2612
    static std::string translatorName( signature ); \
2613
    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
2614
    static std::string translatorName( signature )
2615
2616
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2617
2618
// #included from: internal/catch_approx.hpp
2619
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2620
2621
#include <cmath>
2622
#include <limits>
2623
2624
namespace Catch {
2625
namespace Detail {
2626
2627
    class Approx {
2628
    public:
2629
        explicit Approx ( double value )
2630
        :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2631
            m_scale( 1.0 ),
2632
            m_value( value )
2633
        {}
2634
2635
        Approx( Approx const& other )
2636
        :   m_epsilon( other.m_epsilon ),
2637
            m_scale( other.m_scale ),
2638
            m_value( other.m_value )
2639
        {}
2640
2641
        static Approx custom() {
2642
            return Approx( 0 );
2643
        }
2644
2645
        Approx operator()( double value ) {
2646
            Approx approx( value );
2647
            approx.epsilon( m_epsilon );
2648
            approx.scale( m_scale );
2649
            return approx;
2650
        }
2651
2652
        friend bool operator == ( double lhs, Approx const& rhs ) {
2653
            // Thanks to Richard Harris for his help refining this formula
2654
            return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2655
        }
2656
2657
        friend bool operator == ( Approx const& lhs, double rhs ) {
2658
            return operator==( rhs, lhs );
2659
        }
2660
2661
        friend bool operator != ( double lhs, Approx const& rhs ) {
2662
            return !operator==( lhs, rhs );
2663
        }
2664
2665
        friend bool operator != ( Approx const& lhs, double rhs ) {
2666
            return !operator==( rhs, lhs );
2667
        }
2668
2669
        Approx& epsilon( double newEpsilon ) {
2670
            m_epsilon = newEpsilon;
2671
            return *this;
2672
        }
2673
2674
        Approx& scale( double newScale ) {
2675
            m_scale = newScale;
2676
            return *this;
2677
        }
2678
2679
        std::string toString() const {
2680
            std::ostringstream oss;
2681
            oss << "Approx( " << Catch::toString( m_value ) << " )";
2682
            return oss.str();
2683
        }
2684
2685
    private:
2686
        double m_epsilon;
2687
        double m_scale;
2688
        double m_value;
2689
    };
2690
}
2691
2692
template<>
2693
inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2694
    return value.toString();
2695
}
2696
2697
} // end namespace Catch
2698
2699
// #included from: internal/catch_interfaces_tag_alias_registry.h
2700
#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
2701
2702
// #included from: catch_tag_alias.h
2703
#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
2704
2705
#include <string>
2706
2707
namespace Catch {
2708
2709
    struct TagAlias {
2710
        TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
2711
2712
        std::string tag;
2713
        SourceLineInfo lineInfo;
2714
    };
2715
2716
    struct RegistrarForTagAliases {
2717
        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
2718
    };
2719
2720
} // end namespace Catch
2721
2722
#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
2723
// #included from: catch_option.hpp
2724
#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2725
2726
namespace Catch {
2727
2728
    // An optional type
2729
    template<typename T>
2730
    class Option {
2731
    public:
2732
4
        Option() : nullableValue( CATCH_NULL ) {}
2733
        Option( T const& _value )
2734
        : nullableValue( new( storage ) T( _value ) )
2735
        {}
2736
        Option( Option const& _other )
2737
        : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
2738
        {}
2739
2740
        ~Option() {
2741
4
            reset();
2742
        }
2743
2744
        Option& operator= ( Option const& _other ) {
2745
            if( &_other != this ) {
2746
                reset();
2747
                if( _other )
2748
                    nullableValue = new( storage ) T( *_other );
2749
            }
2750
            return *this;
2751
        }
2752
397
        Option& operator = ( T const& _value ) {
2753
397
            reset();
2754



399
            nullableValue = new( storage ) T( _value );
2755
397
            return *this;
2756
        }
2757
2758
        void reset() {
2759








799
            if( nullableValue )
2760
397
                nullableValue->~T();
2761
796
            nullableValue = CATCH_NULL;
2762
        }
2763
2764
        T& operator*() { return *nullableValue; }
2765
        T const& operator*() const { return *nullableValue; }
2766
        T* operator->() { return nullableValue; }
2767
        const T* operator->() const { return nullableValue; }
2768
2769
        T valueOr( T const& defaultValue ) const {
2770
            return nullableValue ? *nullableValue : defaultValue;
2771
        }
2772
2773
        bool some() const { return nullableValue != CATCH_NULL; }
2774
        bool none() const { return nullableValue == CATCH_NULL; }
2775
2776
        bool operator !() const { return nullableValue == CATCH_NULL; }
2777
        operator SafeBool::type() const {
2778
2
            return SafeBool::makeSafe( some() );
2779
        }
2780
2781
    private:
2782
        T* nullableValue;
2783
        char storage[sizeof(T)];
2784
    };
2785
2786
} // end namespace Catch
2787
2788
namespace Catch {
2789
2790
    struct ITagAliasRegistry {
2791
        virtual ~ITagAliasRegistry();
2792
        virtual Option<TagAlias> find( std::string const& alias ) const = 0;
2793
        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
2794
2795
        static ITagAliasRegistry const& get();
2796
    };
2797
2798
} // end namespace Catch
2799
2800
// These files are included here so the single_include script doesn't put them
2801
// in the conditionally compiled sections
2802
// #included from: internal/catch_test_case_info.h
2803
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2804
2805
#include <string>
2806
#include <set>
2807
2808
#ifdef __clang__
2809
#pragma clang diagnostic push
2810
#pragma clang diagnostic ignored "-Wpadded"
2811
#endif
2812
2813
namespace Catch {
2814
2815
    struct ITestCase;
2816
2817
29368
    struct TestCaseInfo {
2818
        enum SpecialProperties{
2819
            None = 0,
2820
            IsHidden = 1 << 1,
2821
            ShouldFail = 1 << 2,
2822
            MayFail = 1 << 3,
2823
            Throws = 1 << 4
2824
        };
2825
2826
        TestCaseInfo(   std::string const& _name,
2827
                        std::string const& _className,
2828
                        std::string const& _description,
2829
                        std::set<std::string> const& _tags,
2830
                        SourceLineInfo const& _lineInfo );
2831
2832
        TestCaseInfo( TestCaseInfo const& other );
2833
2834
        friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
2835
2836
        bool isHidden() const;
2837
        bool throws() const;
2838
        bool okToFail() const;
2839
        bool expectedToFail() const;
2840
2841
        std::string name;
2842
        std::string className;
2843
        std::string description;
2844
        std::set<std::string> tags;
2845
        std::set<std::string> lcaseTags;
2846
        std::string tagsAsString;
2847
        SourceLineInfo lineInfo;
2848
        SpecialProperties properties;
2849
    };
2850
2851
4182
    class TestCase : public TestCaseInfo {
2852
    public:
2853
2854
        TestCase( ITestCase* testCase, TestCaseInfo const& info );
2855
        TestCase( TestCase const& other );
2856
2857
        TestCase withName( std::string const& _newName ) const;
2858
2859
        void invoke() const;
2860
2861
        TestCaseInfo const& getTestCaseInfo() const;
2862
2863
        void swap( TestCase& other );
2864
        bool operator == ( TestCase const& other ) const;
2865
        bool operator < ( TestCase const& other ) const;
2866
        TestCase& operator = ( TestCase const& other );
2867
2868
    private:
2869
        Ptr<ITestCase> test;
2870
    };
2871
2872
    TestCase makeTestCase(  ITestCase* testCase,
2873
                            std::string const& className,
2874
                            std::string const& name,
2875
                            std::string const& description,
2876
                            SourceLineInfo const& lineInfo );
2877
}
2878
2879
#ifdef __clang__
2880
#pragma clang diagnostic pop
2881
#endif
2882
2883
2884
#ifdef __OBJC__
2885
// #included from: internal/catch_objc.hpp
2886
#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2887
2888
#import <objc/runtime.h>
2889
2890
#include <string>
2891
2892
// NB. Any general catch headers included here must be included
2893
// in catch.hpp first to make sure they are included by the single
2894
// header for non obj-usage
2895
2896
///////////////////////////////////////////////////////////////////////////////
2897
// This protocol is really only here for (self) documenting purposes, since
2898
// all its methods are optional.
2899
@protocol OcFixture
2900
2901
@optional
2902
2903
-(void) setUp;
2904
-(void) tearDown;
2905
2906
@end
2907
2908
namespace Catch {
2909
2910
    class OcMethod : public SharedImpl<ITestCase> {
2911
2912
    public:
2913
        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2914
2915
        virtual void invoke() const {
2916
            id obj = [[m_cls alloc] init];
2917
2918
            performOptionalSelector( obj, @selector(setUp)  );
2919
            performOptionalSelector( obj, m_sel );
2920
            performOptionalSelector( obj, @selector(tearDown)  );
2921
2922
            arcSafeRelease( obj );
2923
        }
2924
    private:
2925
        virtual ~OcMethod() {}
2926
2927
        Class m_cls;
2928
        SEL m_sel;
2929
    };
2930
2931
    namespace Detail{
2932
2933
        inline std::string getAnnotation(   Class cls,
2934
                                            std::string const& annotationName,
2935
                                            std::string const& testCaseName ) {
2936
            NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2937
            SEL sel = NSSelectorFromString( selStr );
2938
            arcSafeRelease( selStr );
2939
            id value = performOptionalSelector( cls, sel );
2940
            if( value )
2941
                return [(NSString*)value UTF8String];
2942
            return "";
2943
        }
2944
    }
2945
2946
    inline size_t registerTestMethods() {
2947
        size_t noTestMethods = 0;
2948
        int noClasses = objc_getClassList( CATCH_NULL, 0 );
2949
2950
        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
2951
        objc_getClassList( classes, noClasses );
2952
2953
        for( int c = 0; c < noClasses; c++ ) {
2954
            Class cls = classes[c];
2955
            {
2956
                u_int count;
2957
                Method* methods = class_copyMethodList( cls, &count );
2958
                for( u_int m = 0; m < count ; m++ ) {
2959
                    SEL selector = method_getName(methods[m]);
2960
                    std::string methodName = sel_getName(selector);
2961
                    if( startsWith( methodName, "Catch_TestCase_" ) ) {
2962
                        std::string testCaseName = methodName.substr( 15 );
2963
                        std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
2964
                        std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
2965
                        const char* className = class_getName( cls );
2966
2967
                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
2968
                        noTestMethods++;
2969
                    }
2970
                }
2971
                free(methods);
2972
            }
2973
        }
2974
        return noTestMethods;
2975
    }
2976
2977
    namespace Matchers {
2978
        namespace Impl {
2979
        namespace NSStringMatchers {
2980
2981
            template<typename MatcherT>
2982
            struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2983
                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2984
                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
2985
                StringHolder() {
2986
                    arcSafeRelease( m_substr );
2987
                }
2988
2989
                NSString* m_substr;
2990
            };
2991
2992
            struct Equals : StringHolder<Equals> {
2993
                Equals( NSString* substr ) : StringHolder( substr ){}
2994
2995
                virtual bool match( ExpressionType const& str ) const {
2996
                    return  (str != nil || m_substr == nil ) &&
2997
                            [str isEqualToString:m_substr];
2998
                }
2999
3000
                virtual std::string toString() const {
3001
                    return "equals string: " + Catch::toString( m_substr );
3002
                }
3003
            };
3004
3005
            struct Contains : StringHolder<Contains> {
3006
                Contains( NSString* substr ) : StringHolder( substr ){}
3007
3008
                virtual bool match( ExpressionType const& str ) const {
3009
                    return  (str != nil || m_substr == nil ) &&
3010
                            [str rangeOfString:m_substr].location != NSNotFound;
3011
                }
3012
3013
                virtual std::string toString() const {
3014
                    return "contains string: " + Catch::toString( m_substr );
3015
                }
3016
            };
3017
3018
            struct StartsWith : StringHolder<StartsWith> {
3019
                StartsWith( NSString* substr ) : StringHolder( substr ){}
3020
3021
                virtual bool match( ExpressionType const& str ) const {
3022
                    return  (str != nil || m_substr == nil ) &&
3023
                            [str rangeOfString:m_substr].location == 0;
3024
                }
3025
3026
                virtual std::string toString() const {
3027
                    return "starts with: " + Catch::toString( m_substr );
3028
                }
3029
            };
3030
            struct EndsWith : StringHolder<EndsWith> {
3031
                EndsWith( NSString* substr ) : StringHolder( substr ){}
3032
3033
                virtual bool match( ExpressionType const& str ) const {
3034
                    return  (str != nil || m_substr == nil ) &&
3035
                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3036
                }
3037
3038
                virtual std::string toString() const {
3039
                    return "ends with: " + Catch::toString( m_substr );
3040
                }
3041
            };
3042
3043
        } // namespace NSStringMatchers
3044
        } // namespace Impl
3045
3046
        inline Impl::NSStringMatchers::Equals
3047
            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3048
3049
        inline Impl::NSStringMatchers::Contains
3050
            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3051
3052
        inline Impl::NSStringMatchers::StartsWith
3053
            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3054
3055
        inline Impl::NSStringMatchers::EndsWith
3056
            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3057
3058
    } // namespace Matchers
3059
3060
    using namespace Matchers;
3061
3062
} // namespace Catch
3063
3064
///////////////////////////////////////////////////////////////////////////////
3065
#define OC_TEST_CASE( name, desc )\
3066
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3067
{\
3068
return @ name; \
3069
}\
3070
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3071
{ \
3072
return @ desc; \
3073
} \
3074
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3075
3076
#endif
3077
3078
#ifdef CATCH_IMPL
3079
// #included from: internal/catch_impl.hpp
3080
#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3081
3082
// Collect all the implementation files together here
3083
// These are the equivalent of what would usually be cpp files
3084
3085
#ifdef __clang__
3086
#pragma clang diagnostic push
3087
#pragma clang diagnostic ignored "-Wweak-vtables"
3088
#endif
3089
3090
// #included from: ../catch_session.hpp
3091
#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3092
3093
// #included from: internal/catch_commandline.hpp
3094
#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3095
3096
// #included from: catch_config.hpp
3097
#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
3098
3099
// #included from: catch_test_spec_parser.hpp
3100
#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
3101
3102
#ifdef __clang__
3103
#pragma clang diagnostic push
3104
#pragma clang diagnostic ignored "-Wpadded"
3105
#endif
3106
3107
// #included from: catch_test_spec.hpp
3108
#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
3109
3110
#ifdef __clang__
3111
#pragma clang diagnostic push
3112
#pragma clang diagnostic ignored "-Wpadded"
3113
#endif
3114
3115
// #included from: catch_wildcard_pattern.hpp
3116
#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3117
3118
namespace Catch
3119
{
3120
    class WildcardPattern {
3121
        enum WildcardPosition {
3122
            NoWildcard = 0,
3123
            WildcardAtStart = 1,
3124
            WildcardAtEnd = 2,
3125
            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3126
        };
3127
3128
    public:
3129
3130
        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
3131
        :   m_caseSensitivity( caseSensitivity ),
3132
            m_wildcard( NoWildcard ),
3133
            m_pattern( adjustCase( pattern ) )
3134
        {
3135
            if( startsWith( m_pattern, "*" ) ) {
3136
                m_pattern = m_pattern.substr( 1 );
3137
                m_wildcard = WildcardAtStart;
3138
            }
3139
            if( endsWith( m_pattern, "*" ) ) {
3140
                m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3141
                m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
3142
            }
3143
        }
3144
        virtual ~WildcardPattern();
3145
        virtual bool matches( std::string const& str ) const {
3146
            switch( m_wildcard ) {
3147
                case NoWildcard:
3148
                    return m_pattern == adjustCase( str );
3149
                case WildcardAtStart:
3150
                    return endsWith( adjustCase( str ), m_pattern );
3151
                case WildcardAtEnd:
3152
                    return startsWith( adjustCase( str ), m_pattern );
3153
                case WildcardAtBothEnds:
3154
                    return contains( adjustCase( str ), m_pattern );
3155
            }
3156
3157
#ifdef __clang__
3158
#pragma clang diagnostic push
3159
#pragma clang diagnostic ignored "-Wunreachable-code"
3160
#endif
3161
            throw std::logic_error( "Unknown enum" );
3162
#ifdef __clang__
3163
#pragma clang diagnostic pop
3164
#endif
3165
        }
3166
    private:
3167
        std::string adjustCase( std::string const& str ) const {
3168
            return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
3169
        }
3170
        CaseSensitive::Choice m_caseSensitivity;
3171
        WildcardPosition m_wildcard;
3172
        std::string m_pattern;
3173
    };
3174
}
3175
3176
#include <string>
3177
#include <vector>
3178
3179
namespace Catch {
3180
3181



12
    class TestSpec {
3182
4
        struct Pattern : SharedImpl<> {
3183
            virtual ~Pattern();
3184
            virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3185
        };
3186
        class NamePattern : public Pattern {
3187
        public:
3188
            NamePattern( std::string const& name )
3189
            : m_wildcardPattern( toLower( name ), CaseSensitive::No )
3190
            {}
3191
            virtual ~NamePattern();
3192
            virtual bool matches( TestCaseInfo const& testCase ) const {
3193
                return m_wildcardPattern.matches( toLower( testCase.name ) );
3194
            }
3195
        private:
3196
            WildcardPattern m_wildcardPattern;
3197
        };
3198
3199
        class TagPattern : public Pattern {
3200
        public:
3201
3
            TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
3202
            virtual ~TagPattern();
3203
395
            virtual bool matches( TestCaseInfo const& testCase ) const {
3204
1580
                return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3205
            }
3206
        private:
3207
            std::string m_tag;
3208
        };
3209
3210
        class ExcludedPattern : public Pattern {
3211
        public:
3212
3
            ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3213
            virtual ~ExcludedPattern();
3214
790
            virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
3215
        private:
3216
            Ptr<Pattern> m_underlyingPattern;
3217
        };
3218
3219

12
        struct Filter {
3220
            std::vector<Ptr<Pattern> > m_patterns;
3221
3222
            bool matches( TestCaseInfo const& testCase ) const {
3223
                // All patterns in a filter must match for the filter to be a match
3224
1975
                for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
3225
790
                    if( !(*it)->matches( testCase ) )
3226
                        return false;
3227
                    return true;
3228
            }
3229
        };
3230
3231
    public:
3232
        bool hasFilters() const {
3233
2
            return !m_filters.empty();
3234
        }
3235
395
        bool matches( TestCaseInfo const& testCase ) const {
3236
            // A TestSpec matches if any filter matches
3237
1580
            for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3238
790
                if( it->matches( testCase ) )
3239
                    return true;
3240
            return false;
3241
        }
3242
3243
    private:
3244
        std::vector<Filter> m_filters;
3245
3246
        friend class TestSpecParser;
3247
    };
3248
}
3249
3250
#ifdef __clang__
3251
#pragma clang diagnostic pop
3252
#endif
3253
3254
namespace Catch {
3255
3256
4
    class TestSpecParser {
3257
        enum Mode{ None, Name, QuotedName, Tag };
3258
        Mode m_mode;
3259
        bool m_exclusion;
3260
        std::size_t m_start, m_pos;
3261
        std::string m_arg;
3262
        TestSpec::Filter m_currentFilter;
3263
        TestSpec m_testSpec;
3264
        ITagAliasRegistry const* m_tagAliases;
3265
3266
    public:
3267
4
        TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
3268
3269
1
        TestSpecParser& parse( std::string const& arg ) {
3270
1
            m_mode = None;
3271
1
            m_exclusion = false;
3272
1
            m_start = std::string::npos;
3273
2
            m_arg = m_tagAliases->expandAliases( arg );
3274
4
            for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3275
6
                visitChar( m_arg[m_pos] );
3276
1
            if( m_mode == Name )
3277
                addPattern<TestSpec::NamePattern>();
3278
1
            return *this;
3279
        }
3280
        TestSpec testSpec() {
3281


1
            addFilter();
3282
2
            return m_testSpec;
3283
        }
3284
    private:
3285
3
        void visitChar( char c ) {
3286
3
            if( m_mode == None ) {
3287

2
                switch( c ) {
3288
                case ' ': return;
3289
1
                case '~': m_exclusion = true; return;
3290
1
                case '[': return startNewMode( Tag, ++m_pos );
3291
                case '"': return startNewMode( QuotedName, ++m_pos );
3292
                default: startNewMode( Name, m_pos ); break;
3293
                }
3294
            }
3295
1
            if( m_mode == Name ) {
3296
                if( c == ',' ) {
3297
                    addPattern<TestSpec::NamePattern>();
3298
                    addFilter();
3299
                }
3300
                else if( c == '[' ) {
3301
                    if( subString() == "exclude:" )
3302
                        m_exclusion = true;
3303
                    else
3304
                        addPattern<TestSpec::NamePattern>();
3305
                    startNewMode( Tag, ++m_pos );
3306
                }
3307
            }
3308

1
            else if( m_mode == QuotedName && c == '"' )
3309
                addPattern<TestSpec::NamePattern>();
3310

1
            else if( m_mode == Tag && c == ']' )
3311
1
                addPattern<TestSpec::TagPattern>();
3312
        }
3313
        void startNewMode( Mode mode, std::size_t start ) {
3314
1
            m_mode = mode;
3315
1
            m_start = start;
3316
        }
3317
1
        std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
3318
        template<typename T>
3319
1
        void addPattern() {
3320
2
            std::string token = subString();
3321



4
            if( startsWith( token, "exclude:" ) ) {
3322
                m_exclusion = true;
3323
                token = token.substr( 8 );
3324
            }
3325

1
            if( !token.empty() ) {
3326


3
                Ptr<TestSpec::Pattern> pattern = new T( token );
3327

1
                if( m_exclusion )
3328

2
                    pattern = new TestSpec::ExcludedPattern( pattern );
3329

1
                m_currentFilter.m_patterns.push_back( pattern );
3330
            }
3331
1
            m_exclusion = false;
3332
1
            m_mode = None;
3333
1
        }
3334
1
        void addFilter() {
3335
2
            if( !m_currentFilter.m_patterns.empty() ) {
3336
1
                m_testSpec.m_filters.push_back( m_currentFilter );
3337
4
                m_currentFilter = TestSpec::Filter();
3338
            }
3339
1
        }
3340
    };
3341
    inline TestSpec parseTestSpec( std::string const& arg ) {
3342
        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3343
    }
3344
3345
} // namespace Catch
3346
3347
#ifdef __clang__
3348
#pragma clang diagnostic pop
3349
#endif
3350
3351
// #included from: catch_interfaces_config.h
3352
#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3353
3354
#include <iostream>
3355
#include <string>
3356
#include <vector>
3357
3358
namespace Catch {
3359
3360
    struct Verbosity { enum Level {
3361
        NoOutput = 0,
3362
        Quiet,
3363
        Normal
3364
    }; };
3365
3366
    struct WarnAbout { enum What {
3367
        Nothing = 0x00,
3368
        NoAssertions = 0x01
3369
    }; };
3370
3371
    struct ShowDurations { enum OrNot {
3372
        DefaultForReporter,
3373
        Always,
3374
        Never
3375
    }; };
3376
    struct RunTests { enum InWhatOrder {
3377
        InDeclarationOrder,
3378
        InLexicographicalOrder,
3379
        InRandomOrder
3380
    }; };
3381
    struct UseColour { enum YesOrNo {
3382
        Auto,
3383
        Yes,
3384
        No
3385
    }; };
3386
3387
    class TestSpec;
3388
3389
2
    struct IConfig : IShared {
3390
3391
        virtual ~IConfig();
3392
3393
        virtual bool allowThrows() const = 0;
3394
        virtual std::ostream& stream() const = 0;
3395
        virtual std::string name() const = 0;
3396
        virtual bool includeSuccessfulResults() const = 0;
3397
        virtual bool shouldDebugBreak() const = 0;
3398
        virtual bool warnAboutMissingAssertions() const = 0;
3399
        virtual int abortAfter() const = 0;
3400
        virtual bool showInvisibles() const = 0;
3401
        virtual ShowDurations::OrNot showDurations() const = 0;
3402
        virtual TestSpec const& testSpec() const = 0;
3403
        virtual RunTests::InWhatOrder runOrder() const = 0;
3404
        virtual unsigned int rngSeed() const = 0;
3405
        virtual UseColour::YesOrNo useColour() const = 0;
3406
    };
3407
}
3408
3409
// #included from: catch_stream.h
3410
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3411
3412
// #included from: catch_streambuf.h
3413
#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
3414
3415
#include <streambuf>
3416
3417
namespace Catch {
3418
3419
    class StreamBufBase : public std::streambuf {
3420
    public:
3421
        virtual ~StreamBufBase() CATCH_NOEXCEPT;
3422
    };
3423
}
3424
3425
#include <streambuf>
3426
#include <ostream>
3427
#include <fstream>
3428
3429
namespace Catch {
3430
3431
    std::ostream& cout();
3432
    std::ostream& cerr();
3433
3434
    struct IStream {
3435
        virtual ~IStream() CATCH_NOEXCEPT;
3436
        virtual std::ostream& stream() const = 0;
3437
    };
3438
3439
    class FileStream : public IStream {
3440
        mutable std::ofstream m_ofs;
3441
    public:
3442
        FileStream( std::string const& filename );
3443
        virtual ~FileStream() CATCH_NOEXCEPT;
3444
    public: // IStream
3445
        virtual std::ostream& stream() const CATCH_OVERRIDE;
3446
    };
3447
3448
    class CoutStream : public IStream {
3449
        mutable std::ostream m_os;
3450
    public:
3451
        CoutStream();
3452
        virtual ~CoutStream() CATCH_NOEXCEPT;
3453
3454
    public: // IStream
3455
        virtual std::ostream& stream() const CATCH_OVERRIDE;
3456
    };
3457
3458
    class DebugOutStream : public IStream {
3459
        std::auto_ptr<StreamBufBase> m_streamBuf;
3460
        mutable std::ostream m_os;
3461
    public:
3462
        DebugOutStream();
3463
        virtual ~DebugOutStream() CATCH_NOEXCEPT;
3464
3465
    public: // IStream
3466
        virtual std::ostream& stream() const CATCH_OVERRIDE;
3467
    };
3468
}
3469
3470
#include <memory>
3471
#include <vector>
3472
#include <string>
3473
#include <iostream>
3474
#include <ctime>
3475
3476
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
3477
#define CATCH_CONFIG_CONSOLE_WIDTH 80
3478
#endif
3479
3480
namespace Catch {
3481
3482

12
    struct ConfigData {
3483
3484
        ConfigData()
3485
1
        :   listTests( false ),
3486
            listTags( false ),
3487
            listReporters( false ),
3488
            listTestNamesOnly( false ),
3489
            showSuccessfulTests( false ),
3490
            shouldDebugBreak( false ),
3491
            noThrow( false ),
3492
            showHelp( false ),
3493
            showInvisibles( false ),
3494
            filenamesAsTags( false ),
3495
            abortAfter( -1 ),
3496
            rngSeed( 0 ),
3497
            verbosity( Verbosity::Normal ),
3498
            warnings( WarnAbout::Nothing ),
3499
            showDurations( ShowDurations::DefaultForReporter ),
3500
            runOrder( RunTests::InDeclarationOrder ),
3501
6
            useColour( UseColour::Auto )
3502
        {}
3503
3504
        bool listTests;
3505
        bool listTags;
3506
        bool listReporters;
3507
        bool listTestNamesOnly;
3508
3509
        bool showSuccessfulTests;
3510
        bool shouldDebugBreak;
3511
        bool noThrow;
3512
        bool showHelp;
3513
        bool showInvisibles;
3514
        bool filenamesAsTags;
3515
3516
        int abortAfter;
3517
        unsigned int rngSeed;
3518
3519
        Verbosity::Level verbosity;
3520
        WarnAbout::What warnings;
3521
        ShowDurations::OrNot showDurations;
3522
        RunTests::InWhatOrder runOrder;
3523
        UseColour::YesOrNo useColour;
3524
3525
        std::string outputFilename;
3526
        std::string name;
3527
        std::string processName;
3528
3529
        std::vector<std::string> reporterNames;
3530
        std::vector<std::string> testsOrTags;
3531
    };
3532
3533
    class Config : public SharedImpl<IConfig> {
3534
    private:
3535
        Config( Config const& other );
3536
        Config& operator = ( Config const& other );
3537
        virtual void dummy();
3538
    public:
3539
3540
        Config()
3541
        {}
3542
3543
1
        Config( ConfigData const& data )
3544
1
        :   m_data( data ),
3545
4
            m_stream( openStream() )
3546
        {
3547
2
            if( !data.testsOrTags.empty() ) {
3548
                TestSpecParser parser( ITagAliasRegistry::get() );
3549
                for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3550
                    parser.parse( data.testsOrTags[i] );
3551
                m_testSpec = parser.testSpec();
3552
            }
3553
1
        }
3554
3555
5
        virtual ~Config() {
3556
2
        }
3557
3558
        std::string const& getFilename() const {
3559
            return m_data.outputFilename ;
3560
        }
3561
3562
        bool listTests() const { return m_data.listTests; }
3563
        bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
3564
        bool listTags() const { return m_data.listTags; }
3565
        bool listReporters() const { return m_data.listReporters; }
3566
3567
        std::string getProcessName() const { return m_data.processName; }
3568
3569
        bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
3570
3571
1
        std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
3572
3573
1153
        int abortAfter() const { return m_data.abortAfter; }
3574
3575
1
        TestSpec const& testSpec() const { return m_testSpec; }
3576
3577
        bool showHelp() const { return m_data.showHelp; }
3578
164047
        bool showInvisibles() const { return m_data.showInvisibles; }
3579
3580
        // IConfig interface
3581
426
        virtual bool allowThrows() const        { return !m_data.noThrow; }
3582
2
        virtual std::ostream& stream() const    { return m_stream->stream(); }
3583
9
        virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }
3584
1433002
        virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }
3585
148
        virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
3586
1167
        virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
3587
3
        virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }
3588
757
        virtual unsigned int rngSeed() const    { return m_data.rngSeed; }
3589
1
        virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
3590
3591
    private:
3592
3593
1
        IStream const* openStream() {
3594
2
            if( m_data.outputFilename.empty() )
3595
1
                return new CoutStream();
3596
            else if( m_data.outputFilename[0] == '%' ) {
3597
                if( m_data.outputFilename == "%debug" )
3598
                    return new DebugOutStream();
3599
                else
3600
                    throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
3601
            }
3602
            else
3603
                return new FileStream( m_data.outputFilename );
3604
        }
3605
        ConfigData m_data;
3606
3607
        std::auto_ptr<IStream const> m_stream;
3608
        TestSpec m_testSpec;
3609
    };
3610
3611
} // end namespace Catch
3612
3613
// #included from: catch_clara.h
3614
#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
3615
3616
// Use Catch's value for console width (store Clara's off to the side, if present)
3617
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
3618
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
3619
#undef CLARA_CONFIG_CONSOLE_WIDTH
3620
#endif
3621
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
3622
3623
// Declare Clara inside the Catch namespace
3624
#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
3625
// #included from: ../external/clara.h
3626
3627
// Version 0.0.2.3
3628
3629
// Only use header guard if we are not using an outer namespace
3630
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
3631
3632
#ifndef STITCH_CLARA_OPEN_NAMESPACE
3633
#define TWOBLUECUBES_CLARA_H_INCLUDED
3634
#define STITCH_CLARA_OPEN_NAMESPACE
3635
#define STITCH_CLARA_CLOSE_NAMESPACE
3636
#else
3637
#define STITCH_CLARA_CLOSE_NAMESPACE }
3638
#endif
3639
3640
#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
3641
3642
// ----------- #included from tbc_text_format.h -----------
3643
3644
// Only use header guard if we are not using an outer namespace
3645
#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
3646
#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3647
#define TBC_TEXT_FORMAT_H_INCLUDED
3648
#endif
3649
3650
#include <string>
3651
#include <vector>
3652
#include <sstream>
3653
#include <algorithm>
3654
3655
// Use optional outer namespace
3656
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3657
namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3658
#endif
3659
3660
namespace Tbc {
3661
3662
#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
3663
    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3664
#else
3665
    const unsigned int consoleWidth = 80;
3666
#endif
3667
3668
    struct TextAttributes {
3669
        TextAttributes()
3670
        :   initialIndent( std::string::npos ),
3671
            indent( 0 ),
3672
            width( consoleWidth-1 ),
3673
            tabChar( '\t' )
3674
        {}
3675
3676
        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
3677
        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
3678
        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
3679
        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
3680
3681
        std::size_t initialIndent;  // indent of first line, or npos
3682
        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
3683
        std::size_t width;          // maximum width of text, including indent. Longer text will wrap
3684
        char tabChar;               // If this char is seen the indent is changed to current pos
3685
    };
3686
3687
    class Text {
3688
    public:
3689
        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
3690
        : attr( _attr )
3691
        {
3692
            std::string wrappableChars = " [({.,/|\\-";
3693
            std::size_t indent = _attr.initialIndent != std::string::npos
3694
                ? _attr.initialIndent
3695
                : _attr.indent;
3696
            std::string remainder = _str;
3697
3698
            while( !remainder.empty() ) {
3699
                if( lines.size() >= 1000 ) {
3700
                    lines.push_back( "... message truncated due to excessive size" );
3701
                    return;
3702
                }
3703
                std::size_t tabPos = std::string::npos;
3704
                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3705
                std::size_t pos = remainder.find_first_of( '\n' );
3706
                if( pos <= width ) {
3707
                    width = pos;
3708
                }
3709
                pos = remainder.find_last_of( _attr.tabChar, width );
3710
                if( pos != std::string::npos ) {
3711
                    tabPos = pos;
3712
                    if( remainder[width] == '\n' )
3713
                        width--;
3714
                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3715
                }
3716
3717
                if( width == remainder.size() ) {
3718
                    spliceLine( indent, remainder, width );
3719
                }
3720
                else if( remainder[width] == '\n' ) {
3721
                    spliceLine( indent, remainder, width );
3722
                    if( width <= 1 || remainder.size() != 1 )
3723
                        remainder = remainder.substr( 1 );
3724
                    indent = _attr.indent;
3725
                }
3726
                else {
3727
                    pos = remainder.find_last_of( wrappableChars, width );
3728
                    if( pos != std::string::npos && pos > 0 ) {
3729
                        spliceLine( indent, remainder, pos );
3730
                        if( remainder[0] == ' ' )
3731
                            remainder = remainder.substr( 1 );
3732
                    }
3733
                    else {
3734
                        spliceLine( indent, remainder, width-1 );
3735
                        lines.back() += "-";
3736
                    }
3737
                    if( lines.size() == 1 )
3738
                        indent = _attr.indent;
3739
                    if( tabPos != std::string::npos )
3740
                        indent += tabPos;
3741
                }
3742
            }
3743
        }
3744
3745
        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3746
            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
3747
            _remainder = _remainder.substr( _pos );
3748
        }
3749
3750
        typedef std::vector<std::string>::const_iterator const_iterator;
3751
3752
        const_iterator begin() const { return lines.begin(); }
3753
        const_iterator end() const { return lines.end(); }
3754
        std::string const& last() const { return lines.back(); }
3755
        std::size_t size() const { return lines.size(); }
3756
        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
3757
        std::string toString() const {
3758
            std::ostringstream oss;
3759
            oss << *this;
3760
            return oss.str();
3761
        }
3762
3763
        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
3764
            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3765
                it != itEnd; ++it ) {
3766
                if( it != _text.begin() )
3767
                    _stream << "\n";
3768
                _stream << *it;
3769
            }
3770
            return _stream;
3771
        }
3772
3773
    private:
3774
        std::string str;
3775
        TextAttributes attr;
3776
        std::vector<std::string> lines;
3777
    };
3778
3779
} // end namespace Tbc
3780
3781
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3782
} // end outer namespace
3783
#endif
3784
3785
#endif // TBC_TEXT_FORMAT_H_INCLUDED
3786
3787
// ----------- end of #include from tbc_text_format.h -----------
3788
// ........... back in clara.h
3789
3790
#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
3791
3792
// ----------- #included from clara_compilers.h -----------
3793
3794
#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3795
#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3796
3797
// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
3798
// The following features are defined:
3799
//
3800
// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
3801
// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
3802
// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
3803
// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
3804
// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
3805
3806
// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
3807
3808
// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
3809
3810
// In general each macro has a _NO_<feature name> form
3811
// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
3812
// Many features, at point of detection, define an _INTERNAL_ macro, so they
3813
// can be combined, en-mass, with the _NO_ forms later.
3814
3815
// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
3816
3817
#ifdef __clang__
3818
3819
#if __has_feature(cxx_nullptr)
3820
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3821
#endif
3822
3823
#if __has_feature(cxx_noexcept)
3824
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3825
#endif
3826
3827
#endif // __clang__
3828
3829
////////////////////////////////////////////////////////////////////////////////
3830
// GCC
3831
#ifdef __GNUC__
3832
3833
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
3834
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3835
#endif
3836
3837
// - otherwise more recent versions define __cplusplus >= 201103L
3838
// and will get picked up below
3839
3840
#endif // __GNUC__
3841
3842
////////////////////////////////////////////////////////////////////////////////
3843
// Visual C++
3844
#ifdef _MSC_VER
3845
3846
#if (_MSC_VER >= 1600)
3847
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3848
#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
3849
#endif
3850
3851
#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
3852
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3853
#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3854
#endif
3855
3856
#endif // _MSC_VER
3857
3858
////////////////////////////////////////////////////////////////////////////////
3859
// C++ language feature support
3860
3861
// catch all support for C++11
3862
#if defined(__cplusplus) && __cplusplus >= 201103L
3863
3864
#define CLARA_CPP11_OR_GREATER
3865
3866
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
3867
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3868
#endif
3869
3870
#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3871
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3872
#endif
3873
3874
#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3875
#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3876
#endif
3877
3878
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
3879
#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
3880
#endif
3881
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
3882
#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
3883
#endif
3884
3885
#endif // __cplusplus >= 201103L
3886
3887
// Now set the actual defines based on the above + anything the user has configured
3888
#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
3889
#define CLARA_CONFIG_CPP11_NULLPTR
3890
#endif
3891
#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
3892
#define CLARA_CONFIG_CPP11_NOEXCEPT
3893
#endif
3894
#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
3895
#define CLARA_CONFIG_CPP11_GENERATED_METHODS
3896
#endif
3897
#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
3898
#define CLARA_CONFIG_CPP11_OVERRIDE
3899
#endif
3900
#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
3901
#define CLARA_CONFIG_CPP11_UNIQUE_PTR
3902
#endif
3903
3904
// noexcept support:
3905
#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
3906
#define CLARA_NOEXCEPT noexcept
3907
#  define CLARA_NOEXCEPT_IS(x) noexcept(x)
3908
#else
3909
#define CLARA_NOEXCEPT throw()
3910
#  define CLARA_NOEXCEPT_IS(x)
3911
#endif
3912
3913
// nullptr support
3914
#ifdef CLARA_CONFIG_CPP11_NULLPTR
3915
#define CLARA_NULL nullptr
3916
#else
3917
#define CLARA_NULL NULL
3918
#endif
3919
3920
// override support
3921
#ifdef CLARA_CONFIG_CPP11_OVERRIDE
3922
#define CLARA_OVERRIDE override
3923
#else
3924
#define CLARA_OVERRIDE
3925
#endif
3926
3927
// unique_ptr support
3928
#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
3929
#   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
3930
#else
3931
#   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
3932
#endif
3933
3934
#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3935
3936
// ----------- end of #include from clara_compilers.h -----------
3937
// ........... back in clara.h
3938
3939
#include <map>
3940
#include <stdexcept>
3941
#include <memory>
3942
3943
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
3944
#define CLARA_PLATFORM_WINDOWS
3945
#endif
3946
3947
// Use optional outer namespace
3948
#ifdef STITCH_CLARA_OPEN_NAMESPACE
3949
STITCH_CLARA_OPEN_NAMESPACE
3950
#endif
3951
3952
namespace Clara {
3953
3954
    struct UnpositionalTag {};
3955
3956
    extern UnpositionalTag _;
3957
3958
#ifdef CLARA_CONFIG_MAIN
3959
    UnpositionalTag _;
3960
#endif
3961
3962
    namespace Detail {
3963
3964
#ifdef CLARA_CONSOLE_WIDTH
3965
    const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3966
#else
3967
    const unsigned int consoleWidth = 80;
3968
#endif
3969
3970
        using namespace Tbc;
3971
3972
56
        inline bool startsWith( std::string const& str, std::string const& prefix ) {
3973

112
            return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3974
        }
3975
3976
        template<typename T> struct RemoveConstRef{ typedef T type; };
3977
        template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
3978
        template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
3979
        template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
3980
3981
        template<typename T>    struct IsBool       { static const bool value = false; };
3982
        template<>              struct IsBool<bool> { static const bool value = true; };
3983
3984
        template<typename T>
3985
        void convertInto( std::string const& _source, T& _dest ) {
3986
            std::stringstream ss;
3987
            ss << _source;
3988
            ss >> _dest;
3989
            if( ss.fail() )
3990
                throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
3991
        }
3992
        inline void convertInto( std::string const& _source, std::string& _dest ) {
3993
1
            _dest = _source;
3994
        }
3995
        inline void convertInto( std::string const& _source, bool& _dest ) {
3996
            std::string sourceLC = _source;
3997
            std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3998
            if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
3999
                _dest = true;
4000
            else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
4001
                _dest = false;
4002
            else
4003
                throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
4004
        }
4005
4006
        template<typename ConfigT>
4007
        struct IArgFunction {
4008
            virtual ~IArgFunction() {}
4009
#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
4010
            IArgFunction()                      = default;
4011
55
            IArgFunction( IArgFunction const& ) = default;
4012
#endif
4013
            virtual void set( ConfigT& config, std::string const& value ) const = 0;
4014
            virtual bool takesArg() const = 0;
4015
            virtual IArgFunction* clone() const = 0;
4016
        };
4017
4018
        template<typename ConfigT>
4019
        class BoundArgFunction {
4020
        public:
4021
23
            BoundArgFunction() : functionObj( CLARA_NULL ) {}
4022
25
            BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
4023

53
            BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
4024
24
            BoundArgFunction& operator = ( BoundArgFunction const& other ) {
4025
24
                IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
4026
24
                delete functionObj;
4027
24
                functionObj = newFunctionObj;
4028
24
                return *this;
4029
            }
4030








101
            ~BoundArgFunction() { delete functionObj; }
4031
4032
            void set( ConfigT& config, std::string const& value ) const {
4033


1
                functionObj->set( config, value );
4034
            }
4035
            bool takesArg() const { return functionObj->takesArg(); }
4036
4037
            bool isSet() const {
4038
22
                return functionObj != CLARA_NULL;
4039
            }
4040
        private:
4041
            IArgFunction<ConfigT>* functionObj;
4042
        };
4043
4044
        template<typename C>
4045
2
        struct NullBinder : IArgFunction<C>{
4046
            virtual void set( C&, std::string const& ) const {}
4047
            virtual bool takesArg() const { return true; }
4048
            virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
4049
        };
4050
4051
        template<typename C, typename M>
4052
127
        struct BoundDataMember : IArgFunction<C>{
4053
13
            BoundDataMember( M C::* _member ) : member( _member ) {}
4054
1
            virtual void set( C& p, std::string const& stringValue ) const {
4055
2
                convertInto( stringValue, p.*member );
4056
1
            }
4057
            virtual bool takesArg() const { return !IsBool<M>::value; }
4058
76
            virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
4059
            M C::* member;
4060
        };
4061
        template<typename C, typename M>
4062
        struct BoundUnaryMethod : IArgFunction<C>{
4063
            BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
4064
            virtual void set( C& p, std::string const& stringValue ) const {
4065
                typename RemoveConstRef<M>::type value;
4066
                convertInto( stringValue, value );
4067
                (p.*member)( value );
4068
            }
4069
            virtual bool takesArg() const { return !IsBool<M>::value; }
4070
            virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
4071
            void (C::*member)( M );
4072
        };
4073
        template<typename C>
4074
        struct BoundNullaryMethod : IArgFunction<C>{
4075
            BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
4076
            virtual void set( C& p, std::string const& stringValue ) const {
4077
                bool value;
4078
                convertInto( stringValue, value );
4079
                if( value )
4080
                    (p.*member)();
4081
            }
4082
            virtual bool takesArg() const { return false; }
4083
            virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
4084
            void (C::*member)();
4085
        };
4086
4087
        template<typename C>
4088
11
        struct BoundUnaryFunction : IArgFunction<C>{
4089
2
            BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
4090
            virtual void set( C& obj, std::string const& stringValue ) const {
4091
                bool value;
4092
                convertInto( stringValue, value );
4093
                if( value )
4094
                    function( obj );
4095
            }
4096
            virtual bool takesArg() const { return false; }
4097
6
            virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
4098
            void (*function)( C& );
4099
        };
4100
4101
        template<typename C, typename T>
4102
51
        struct BoundBinaryFunction : IArgFunction<C>{
4103
9
            BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
4104
            virtual void set( C& obj, std::string const& stringValue ) const {
4105
                typename RemoveConstRef<T>::type value;
4106
                convertInto( stringValue, value );
4107
                function( obj, value );
4108
            }
4109
            virtual bool takesArg() const { return !IsBool<T>::value; }
4110
28
            virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
4111
            void (*function)( C&, T );
4112
        };
4113
4114
    } // namespace Detail
4115
4116
1
    inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
4117
2
        std::vector<std::string> args( static_cast<std::size_t>( argc ) );
4118
2
        for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
4119
3
            args[i] = argv[i];
4120
4121
1
        return args;
4122
    }
4123
4124
    class Parser {
4125
        enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
4126
        Mode mode;
4127
        std::size_t from;
4128
        bool inQuotes;
4129
    public:
4130
4131
        struct Token {
4132
            enum Type { Positional, ShortOpt, LongOpt };
4133
            Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
4134
            Type type;
4135
            std::string data;
4136
        };
4137
4138
1
        Parser() : mode( None ), from( 0 ), inQuotes( false ){}
4139
4140
1
        void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
4141
3
            const std::string doubleDash = "--";
4142

1
            for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
4143
                parseIntoTokens( args[i], tokens);
4144
1
        }
4145
4146
        void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
4147
            for( std::size_t i = 0; i <= arg.size(); ++i ) {
4148
                char c = arg[i];
4149
                if( c == '"' )
4150
                    inQuotes = !inQuotes;
4151
                mode = handleMode( i, c, arg, tokens );
4152
            }
4153
        }
4154
        Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4155
            switch( mode ) {
4156
                case None: return handleNone( i, c );
4157
                case MaybeShortOpt: return handleMaybeShortOpt( i, c );
4158
                case ShortOpt:
4159
                case LongOpt:
4160
                case SlashOpt: return handleOpt( i, c, arg, tokens );
4161
                case Positional: return handlePositional( i, c, arg, tokens );
4162
                default: throw std::logic_error( "Unknown mode" );
4163
            }
4164
        }
4165
4166
        Mode handleNone( std::size_t i, char c ) {
4167
            if( inQuotes ) {
4168
                from = i;
4169
                return Positional;
4170
            }
4171
            switch( c ) {
4172
                case '-': return MaybeShortOpt;
4173
#ifdef CLARA_PLATFORM_WINDOWS
4174
                case '/': from = i+1; return SlashOpt;
4175
#endif
4176
                default: from = i; return Positional;
4177
            }
4178
        }
4179
        Mode handleMaybeShortOpt( std::size_t i, char c ) {
4180
            switch( c ) {
4181
                case '-': from = i+1; return LongOpt;
4182
                default: from = i; return ShortOpt;
4183
            }
4184
        }
4185
        Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4186
            if( std::string( " \t:=\0", 5 ).find( c ) == std::string::npos )
4187
                return mode;
4188
4189
            std::string optName = arg.substr( from, i-from );
4190
            if( mode == ShortOpt )
4191
                for( std::size_t j = 0; j < optName.size(); ++j )
4192
                    tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
4193
            else if( mode == SlashOpt && optName.size() == 1 )
4194
                tokens.push_back( Token( Token::ShortOpt, optName ) );
4195
            else
4196
                tokens.push_back( Token( Token::LongOpt, optName ) );
4197
            return None;
4198
        }
4199
        Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4200
            if( inQuotes || std::string( " \t\0", 3 ).find( c ) == std::string::npos )
4201
                return mode;
4202
4203
            std::string data = arg.substr( from, i-from );
4204
            tokens.push_back( Token( Token::Positional, data ) );
4205
            return None;
4206
        }
4207
    };
4208
4209
    template<typename ConfigT>
4210
645
    struct CommonArgProperties {
4211
115
        CommonArgProperties() {}
4212
        CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
4213
4214
        Detail::BoundArgFunction<ConfigT> boundField;
4215
        std::string description;
4216
        std::string detail;
4217
        std::string placeholder; // Only value if boundField takes an arg
4218
4219
        bool takesArg() const {
4220
            return !placeholder.empty();
4221
        }
4222
22
        void validate() const {
4223
44
            if( !boundField.isSet() )
4224
                throw std::logic_error( "option not bound" );
4225
22
        }
4226
    };
4227
349
    struct OptionArgProperties {
4228
        std::vector<std::string> shortNames;
4229
        std::string longName;
4230
4231
        bool hasShortName( std::string const& shortName ) const {
4232
            return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4233
        }
4234
        bool hasLongName( std::string const& _longName ) const {
4235
            return _longName == longName;
4236
        }
4237
    };
4238
    struct PositionalArgProperties {
4239
23
        PositionalArgProperties() : position( -1 ) {}
4240
        int position; // -1 means non-positional (floating)
4241
4242
        bool isFixedPositional() const {
4243
            return position != -1;
4244
        }
4245
    };
4246
4247
    template<typename ConfigT>
4248
4
    class CommandLine {
4249
4250
151
        struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
4251
92
            Arg() {}
4252
            Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4253
4254
            using CommonArgProperties<ConfigT>::placeholder; // !TBD
4255
4256
            std::string dbgName() const {
4257
                if( !longName.empty() )
4258
                    return "--" + longName;
4259
                if( !shortNames.empty() )
4260
                    return "-" + shortNames[0];
4261
                return "positional args";
4262
            }
4263
            std::string commands() const {
4264
                std::ostringstream oss;
4265
                bool first = true;
4266
                std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4267
                for(; it != itEnd; ++it ) {
4268
                    if( first )
4269
                        first = false;
4270
                    else
4271
                        oss << ", ";
4272
                    oss << "-" << *it;
4273
                }
4274
                if( !longName.empty() ) {
4275
                    if( !first )
4276
                        oss << ", ";
4277
                    oss << "--" << longName;
4278
                }
4279
                if( !placeholder.empty() )
4280
                    oss << " <" << placeholder << ">";
4281
                return oss.str();
4282
            }
4283
        };
4284
4285
        typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
4286
4287
39
        friend void addOptName( Arg& arg, std::string const& optName )
4288
        {
4289
39
            if( optName.empty() )
4290
                return;
4291

156
            if( Detail::startsWith( optName, "--" ) ) {
4292
44
                if( !arg.longName.empty() )
4293
                    throw std::logic_error( "Only one long opt may be specified. '"
4294
                        + arg.longName
4295
                        + "' already specified, now attempting to add '"
4296
                        + optName + "'" );
4297
44
                arg.longName = optName.substr( 2 );
4298
            }
4299

68
            else if( Detail::startsWith( optName, "-" ) )
4300
51
                arg.shortNames.push_back( optName.substr( 1 ) );
4301
            else
4302
                throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
4303
        }
4304
        friend void setPositionalArg( Arg& arg, int position )
4305
        {
4306
            arg.position = position;
4307
        }
4308
4309
        class ArgBuilder {
4310
        public:
4311
23
            ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4312
4313
            // Bind a non-boolean data member (requires placeholder string)
4314
            template<typename C, typename M>
4315
2
            void bind( M C::* field, std::string const& placeholder ) {
4316
8
                m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
4317
4
                m_arg->placeholder = placeholder;
4318
2
            }
4319
            // Bind a boolean data member (no placeholder required)
4320
            template<typename C>
4321
10
            void bind( bool C::* field ) {
4322
40
                m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
4323
10
            }
4324
4325
            // Bind a method taking a single, non-boolean argument (requires a placeholder string)
4326
            template<typename C, typename M>
4327
            void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
4328
                m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4329
                m_arg->placeholder = placeholder;
4330
            }
4331
4332
            // Bind a method taking a single, boolean argument (no placeholder string required)
4333
            template<typename C>
4334
            void bind( void (C::* unaryMethod)( bool ) ) {
4335
                m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4336
            }
4337
4338
            // Bind a method that takes no arguments (will be called if opt is present)
4339
            template<typename C>
4340
            void bind( void (C::* nullaryMethod)() ) {
4341
                m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
4342
            }
4343
4344
            // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
4345
            template<typename C>
4346
2
            void bind( void (* unaryFunction)( C& ) ) {
4347
8
                m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
4348
2
            }
4349
4350
            // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
4351
            template<typename C, typename T>
4352
9
            void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
4353

36
                m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4354
18
                m_arg->placeholder = placeholder;
4355
9
            }
4356
4357
            ArgBuilder& describe( std::string const& description ) {
4358
46
                m_arg->description = description;
4359
                return *this;
4360
            }
4361
            ArgBuilder& detail( std::string const& detail ) {
4362
                m_arg->detail = detail;
4363
                return *this;
4364
            }
4365
4366
        protected:
4367
            Arg* m_arg;
4368
        };
4369
4370
        class OptBuilder : public ArgBuilder {
4371
        public:
4372
44
            OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
4373
            OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4374
4375
            OptBuilder& operator[]( std::string const& optName ) {
4376








17
                addOptName( *ArgBuilder::m_arg, optName );
4377
                return *this;
4378
            }
4379
        };
4380
4381
    public:
4382
4383
1
        CommandLine()
4384
1
        :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
4385
            m_highestSpecifiedArgPosition( 0 ),
4386
5
            m_throwOnUnrecognisedTokens( false )
4387
1
        {}
4388
        CommandLine( CommandLine const& other )
4389
        :   m_boundProcessName( other.m_boundProcessName ),
4390
            m_options ( other.m_options ),
4391
            m_positionalArgs( other.m_positionalArgs ),
4392
            m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4393
            m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4394
        {
4395
            if( other.m_floatingArg.get() )
4396
                m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
4397
        }
4398
4399
        CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
4400
1
            m_throwOnUnrecognisedTokens = shouldThrow;
4401
            return *this;
4402
        }
4403
4404
22
        OptBuilder operator[]( std::string const& optName ) {
4405
66
            m_options.push_back( Arg() );
4406
44
            addOptName( m_options.back(), optName );
4407
66
            OptBuilder builder( &m_options.back() );
4408
22
            return builder;
4409
        }
4410
4411
        ArgBuilder operator[]( int position ) {
4412
            m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4413
            if( position > m_highestSpecifiedArgPosition )
4414
                m_highestSpecifiedArgPosition = position;
4415
            setPositionalArg( m_positionalArgs[position], position );
4416
            ArgBuilder builder( &m_positionalArgs[position] );
4417
            return builder;
4418
        }
4419
4420
        // Invoke this with the _ instance
4421
1
        ArgBuilder operator[]( UnpositionalTag ) {
4422
2
            if( m_floatingArg.get() )
4423
                throw std::logic_error( "Only one unpositional argument can be added" );
4424
3
            m_floatingArg.reset( new Arg() );
4425
3
            ArgBuilder builder( m_floatingArg.get() );
4426
1
            return builder;
4427
        }
4428
4429
        template<typename C, typename M>
4430
1
        void bindProcessName( M C::* field ) {
4431
4
            m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
4432
1
        }
4433
        template<typename C, typename M>
4434
        void bindProcessName( void (C::*_unaryMethod)( M ) ) {
4435
            m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4436
        }
4437
4438
        void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
4439
            typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4440
            std::size_t maxWidth = 0;
4441
            for( it = itBegin; it != itEnd; ++it )
4442
                maxWidth = (std::max)( maxWidth, it->commands().size() );
4443
4444
            for( it = itBegin; it != itEnd; ++it ) {
4445
                Detail::Text usage( it->commands(), Detail::TextAttributes()
4446
                                                        .setWidth( maxWidth+indent )
4447
                                                        .setIndent( indent ) );
4448
                Detail::Text desc( it->description, Detail::TextAttributes()
4449
                                                        .setWidth( width - maxWidth - 3 ) );
4450
4451
                for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4452
                    std::string usageCol = i < usage.size() ? usage[i] : "";
4453
                    os << usageCol;
4454
4455
                    if( i < desc.size() && !desc[i].empty() )
4456
                        os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
4457
                            << desc[i];
4458
                    os << "\n";
4459
                }
4460
            }
4461
        }
4462
        std::string optUsage() const {
4463
            std::ostringstream oss;
4464
            optUsage( oss );
4465
            return oss.str();
4466
        }
4467
4468
        void argSynopsis( std::ostream& os ) const {
4469
            for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4470
                if( i > 1 )
4471
                    os << " ";
4472
                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4473
                if( it != m_positionalArgs.end() )
4474
                    os << "<" << it->second.placeholder << ">";
4475
                else if( m_floatingArg.get() )
4476
                    os << "<" << m_floatingArg->placeholder << ">";
4477
                else
4478
                    throw std::logic_error( "non consecutive positional arguments with no floating args" );
4479
            }
4480
            // !TBD No indication of mandatory args
4481
            if( m_floatingArg.get() ) {
4482
                if( m_highestSpecifiedArgPosition > 1 )
4483
                    os << " ";
4484
                os << "[<" << m_floatingArg->placeholder << "> ...]";
4485
            }
4486
        }
4487
        std::string argSynopsis() const {
4488
            std::ostringstream oss;
4489
            argSynopsis( oss );
4490
            return oss.str();
4491
        }
4492
4493
        void usage( std::ostream& os, std::string const& procName ) const {
4494
            validate();
4495
            os << "usage:\n  " << procName << " ";
4496
            argSynopsis( os );
4497
            if( !m_options.empty() ) {
4498
                os << " [options]\n\nwhere options are: \n";
4499
                optUsage( os, 2 );
4500
            }
4501
            os << "\n";
4502
        }
4503
        std::string usage( std::string const& procName ) const {
4504
            std::ostringstream oss;
4505
            usage( oss, procName );
4506
            return oss.str();
4507
        }
4508
4509
        ConfigT parse( std::vector<std::string> const& args ) const {
4510
            ConfigT config;
4511
            parseInto( args, config );
4512
            return config;
4513
        }
4514
4515
1
        std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
4516
3
            std::string processName = args[0];
4517
1
            std::size_t lastSlash = processName.find_last_of( "/\\" );
4518
1
            if( lastSlash != std::string::npos )
4519
2
                processName = processName.substr( lastSlash+1 );
4520
2
            m_boundProcessName.set( config, processName );
4521
2
            std::vector<Parser::Token> tokens;
4522
1
            Parser parser;
4523
1
            parser.parseIntoTokens( args, tokens );
4524
2
            return populate( tokens, config );
4525
        }
4526
4527
1
        std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4528
1
            validate();
4529
1
            std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4530
2
            unusedTokens = populateFixedArgs( unusedTokens, config );
4531
2
            unusedTokens = populateFloatingArgs( unusedTokens, config );
4532
1
            return unusedTokens;
4533
        }
4534
4535
1
        std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4536
1
            std::vector<Parser::Token> unusedTokens;
4537
2
            std::vector<std::string> errors;
4538
2
            for( std::size_t i = 0; i < tokens.size(); ++i ) {
4539
                Parser::Token const& token = tokens[i];
4540
                typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4541
                for(; it != itEnd; ++it ) {
4542
                    Arg const& arg = *it;
4543
4544
                    try {
4545
                        if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4546
                            ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4547
                            if( arg.takesArg() ) {
4548
                                if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4549
                                    errors.push_back( "Expected argument to option: " + token.data );
4550
                                else
4551
                                    arg.boundField.set( config, tokens[++i].data );
4552
                            }
4553
                            else {
4554
                                arg.boundField.set( config, "true" );
4555
                            }
4556
                            break;
4557
                        }
4558
                    }
4559
                    catch( std::exception& ex ) {
4560
                        errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
4561
                    }
4562
                }
4563
                if( it == itEnd ) {
4564
                    if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4565
                        unusedTokens.push_back( token );
4566
                    else if( errors.empty() && m_throwOnUnrecognisedTokens )
4567
                        errors.push_back( "unrecognised option: " + token.data );
4568
                }
4569
            }
4570
1
            if( !errors.empty() ) {
4571
                std::ostringstream oss;
4572
                for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4573
                        it != itEnd;
4574
                        ++it ) {
4575
                    if( it != errors.begin() )
4576
                        oss << "\n";
4577
                    oss << *it;
4578
                }
4579
                throw std::runtime_error( oss.str() );
4580
            }
4581
1
            return unusedTokens;
4582
        }
4583
1
        std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4584
1
            std::vector<Parser::Token> unusedTokens;
4585
1
            int position = 1;
4586
2
            for( std::size_t i = 0; i < tokens.size(); ++i ) {
4587
                Parser::Token const& token = tokens[i];
4588
                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4589
                if( it != m_positionalArgs.end() )
4590
                    it->second.boundField.set( config, token.data );
4591
                else
4592
                    unusedTokens.push_back( token );
4593
                if( token.type == Parser::Token::Positional )
4594
                    position++;
4595
            }
4596
1
            return unusedTokens;
4597
        }
4598
1
        std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4599
2
            if( !m_floatingArg.get() )
4600
                return tokens;
4601
2
            std::vector<Parser::Token> unusedTokens;
4602
2
            for( std::size_t i = 0; i < tokens.size(); ++i ) {
4603
                Parser::Token const& token = tokens[i];
4604
                if( token.type == Parser::Token::Positional )
4605
                    m_floatingArg->boundField.set( config, token.data );
4606
                else
4607
                    unusedTokens.push_back( token );
4608
            }
4609
1
            return unusedTokens;
4610
        }
4611
4612
1
        void validate() const
4613
        {
4614


2
            if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4615
                throw std::logic_error( "No options or arguments specified" );
4616
4617
23
            for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
4618
                                                            itEnd = m_options.end();
4619
                    it != itEnd; ++it )
4620
22
                it->validate();
4621
1
        }
4622
4623
    private:
4624
        Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4625
        std::vector<Arg> m_options;
4626
        std::map<int, Arg> m_positionalArgs;
4627
        ArgAutoPtr m_floatingArg;
4628
        int m_highestSpecifiedArgPosition;
4629
        bool m_throwOnUnrecognisedTokens;
4630
    };
4631
4632
} // end namespace Clara
4633
4634
STITCH_CLARA_CLOSE_NAMESPACE
4635
#undef STITCH_CLARA_OPEN_NAMESPACE
4636
#undef STITCH_CLARA_CLOSE_NAMESPACE
4637
4638
#endif // TWOBLUECUBES_CLARA_H_INCLUDED
4639
#undef STITCH_CLARA_OPEN_NAMESPACE
4640
4641
// Restore Clara's value for console width, if present
4642
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4643
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4644
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4645
#endif
4646
4647
#include <fstream>
4648
4649
namespace Catch {
4650
4651
    inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
4652
    inline void abortAfterX( ConfigData& config, int x ) {
4653
        if( x < 1 )
4654
            throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
4655
        config.abortAfter = x;
4656
    }
4657
    inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
4658
    inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
4659
4660
    inline void addWarning( ConfigData& config, std::string const& _warning ) {
4661
        if( _warning == "NoAssertions" )
4662
            config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
4663
        else
4664
            throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
4665
    }
4666
    inline void setOrder( ConfigData& config, std::string const& order ) {
4667
        if( startsWith( "declared", order ) )
4668
            config.runOrder = RunTests::InDeclarationOrder;
4669
        else if( startsWith( "lexical", order ) )
4670
            config.runOrder = RunTests::InLexicographicalOrder;
4671
        else if( startsWith( "random", order ) )
4672
            config.runOrder = RunTests::InRandomOrder;
4673
        else
4674
            throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
4675
    }
4676
    inline void setRngSeed( ConfigData& config, std::string const& seed ) {
4677
        if( seed == "time" ) {
4678
            config.rngSeed = static_cast<unsigned int>( std::time(0) );
4679
        }
4680
        else {
4681
            std::stringstream ss;
4682
            ss << seed;
4683
            ss >> config.rngSeed;
4684
            if( ss.fail() )
4685
                throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
4686
        }
4687
    }
4688
    inline void setVerbosity( ConfigData& config, int level ) {
4689
        // !TBD: accept strings?
4690
        config.verbosity = static_cast<Verbosity::Level>( level );
4691
    }
4692
    inline void setShowDurations( ConfigData& config, bool _showDurations ) {
4693
        config.showDurations = _showDurations
4694
            ? ShowDurations::Always
4695
            : ShowDurations::Never;
4696
    }
4697
    inline void setUseColour( ConfigData& config, std::string const& value ) {
4698
        std::string mode = toLower( value );
4699
4700
        if( mode == "yes" )
4701
            config.useColour = UseColour::Yes;
4702
        else if( mode == "no" )
4703
            config.useColour = UseColour::No;
4704
        else if( mode == "auto" )
4705
            config.useColour = UseColour::Auto;
4706
        else
4707
            throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
4708
    }
4709
    inline void forceColour( ConfigData& config ) {
4710
        config.useColour = UseColour::Yes;
4711
    }
4712
    inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
4713
        std::ifstream f( _filename.c_str() );
4714
        if( !f.is_open() )
4715
            throw std::domain_error( "Unable to load input file: " + _filename );
4716
4717
        std::string line;
4718
        while( std::getline( f, line ) ) {
4719
            line = trim(line);
4720
            if( !line.empty() && !startsWith( line, "#" ) )
4721
                addTestOrTags( config, "\"" + line + "\"," );
4722
        }
4723
    }
4724
4725
1
    inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4726
4727
        using namespace Clara;
4728
1
        CommandLine<ConfigData> cli;
4729
4730
1
        cli.bindProcessName( &ConfigData::processName );
4731
4732


13
        cli["-?"]["-h"]["--help"]
4733
6
            .describe( "display usage information" )
4734
1
            .bind( &ConfigData::showHelp );
4735
4736

9
        cli["-l"]["--list-tests"]
4737
6
            .describe( "list all/matching test cases" )
4738
1
            .bind( &ConfigData::listTests );
4739
4740

9
        cli["-t"]["--list-tags"]
4741
6
            .describe( "list all/matching tags" )
4742
1
            .bind( &ConfigData::listTags );
4743
4744

9
        cli["-s"]["--success"]
4745
6
            .describe( "include successful tests in output" )
4746
1
            .bind( &ConfigData::showSuccessfulTests );
4747
4748

9
        cli["-b"]["--break"]
4749
6
            .describe( "break into debugger on failure" )
4750
1
            .bind( &ConfigData::shouldDebugBreak );
4751
4752

9
        cli["-e"]["--nothrow"]
4753
6
            .describe( "skip exception tests" )
4754
1
            .bind( &ConfigData::noThrow );
4755
4756

9
        cli["-i"]["--invisibles"]
4757
6
            .describe( "show invisibles (tabs, newlines)" )
4758
1
            .bind( &ConfigData::showInvisibles );
4759
4760

9
        cli["-o"]["--out"]
4761
6
            .describe( "output filename" )
4762

5
            .bind( &ConfigData::outputFilename, "filename" );
4763
4764

9
        cli["-r"]["--reporter"]
4765
//            .placeholder( "name[:filename]" )
4766
6
            .describe( "reporter to use (defaults to console)" )
4767

5
            .bind( &addReporterName, "name" );
4768
4769

9
        cli["-n"]["--name"]
4770
6
            .describe( "suite name" )
4771

5
            .bind( &ConfigData::name, "name" );
4772
4773

9
        cli["-a"]["--abort"]
4774
6
            .describe( "abort at first failure" )
4775
1
            .bind( &abortAfterFirst );
4776
4777

9
        cli["-x"]["--abortx"]
4778
6
            .describe( "abort after x failures" )
4779

5
            .bind( &abortAfterX, "no. failures" );
4780
4781

9
        cli["-w"]["--warn"]
4782
6
            .describe( "enable warnings" )
4783

5
            .bind( &addWarning, "warning name" );
4784
4785
// - needs updating if reinstated
4786
//        cli.into( &setVerbosity )
4787
//            .describe( "level of verbosity (0=no output)" )
4788
//            .shortOpt( "v")
4789
//            .longOpt( "verbosity" )
4790
//            .placeholder( "level" );
4791
4792
2
        cli[_]
4793
5
            .describe( "which test or tests to use" )
4794

5
            .bind( &addTestOrTags, "test name, pattern or tags" );
4795
4796

9
        cli["-d"]["--durations"]
4797
6
            .describe( "show test durations" )
4798

5
            .bind( &setShowDurations, "yes|no" );
4799
4800

9
        cli["-f"]["--input-file"]
4801
6
            .describe( "load test names to run from a file" )
4802

5
            .bind( &loadTestNamesFromFile, "filename" );
4803
4804

9
        cli["-#"]["--filenames-as-tags"]
4805
6
            .describe( "adds a tag for the filename" )
4806
1
            .bind( &ConfigData::filenamesAsTags );
4807
4808
        // Less common commands which don't have a short form
4809
        cli["--list-test-names-only"]
4810

9
            .describe( "list all/matching test cases names only" )
4811
1
            .bind( &ConfigData::listTestNamesOnly );
4812
4813
        cli["--list-reporters"]
4814

9
            .describe( "list all reporters" )
4815
1
            .bind( &ConfigData::listReporters );
4816
4817
        cli["--order"]
4818

9
            .describe( "test case order (defaults to decl)" )
4819

5
            .bind( &setOrder, "decl|lex|rand" );
4820
4821
        cli["--rng-seed"]
4822

9
            .describe( "set a specific seed for random numbers" )
4823

5
            .bind( &setRngSeed, "'time'|number" );
4824
4825
        cli["--force-colour"]
4826

9
            .describe( "force colourised output (deprecated)" )
4827
1
            .bind( &forceColour );
4828
4829
        cli["--use-colour"]
4830

9
            .describe( "should output be colourised" )
4831

5
            .bind( &setUseColour, "yes|no" );
4832
4833
1
        return cli;
4834
    }
4835
4836
} // end namespace Catch
4837
4838
// #included from: internal/catch_list.hpp
4839
#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
4840
4841
// #included from: catch_text.h
4842
#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
4843
4844
#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4845
4846
#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
4847
// #included from: ../external/tbc_text_format.h
4848
// Only use header guard if we are not using an outer namespace
4849
#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4850
# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4851
#  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4852
#   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4853
#  endif
4854
# else
4855
#  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4856
# endif
4857
#endif
4858
#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4859
#include <string>
4860
#include <vector>
4861
#include <sstream>
4862
4863
// Use optional outer namespace
4864
#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4865
namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4866
#endif
4867
4868
namespace Tbc {
4869
4870
#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4871
    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4872
#else
4873
    const unsigned int consoleWidth = 80;
4874
#endif
4875
4876
    struct TextAttributes {
4877
        TextAttributes()
4878
        :   initialIndent( std::string::npos ),
4879
            indent( 0 ),
4880
            width( consoleWidth-1 ),
4881
            tabChar( '\t' )
4882
        {}
4883
4884
        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
4885
        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
4886
        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
4887
        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
4888
4889
        std::size_t initialIndent;  // indent of first line, or npos
4890
        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
4891
        std::size_t width;          // maximum width of text, including indent. Longer text will wrap
4892
        char tabChar;               // If this char is seen the indent is changed to current pos
4893
    };
4894
4895
    class Text {
4896
    public:
4897
        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
4898
        : attr( _attr )
4899
        {
4900
            std::string wrappableChars = " [({.,/|\\-";
4901
            std::size_t indent = _attr.initialIndent != std::string::npos
4902
                ? _attr.initialIndent
4903
                : _attr.indent;
4904
            std::string remainder = _str;
4905
4906
            while( !remainder.empty() ) {
4907
                if( lines.size() >= 1000 ) {
4908
                    lines.push_back( "... message truncated due to excessive size" );
4909
                    return;
4910
                }
4911
                std::size_t tabPos = std::string::npos;
4912
                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4913
                std::size_t pos = remainder.find_first_of( '\n' );
4914
                if( pos <= width ) {
4915
                    width = pos;
4916
                }
4917
                pos = remainder.find_last_of( _attr.tabChar, width );
4918
                if( pos != std::string::npos ) {
4919
                    tabPos = pos;
4920
                    if( remainder[width] == '\n' )
4921
                        width--;
4922
                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4923
                }
4924
4925
                if( width == remainder.size() ) {
4926
                    spliceLine( indent, remainder, width );
4927
                }
4928
                else if( remainder[width] == '\n' ) {
4929
                    spliceLine( indent, remainder, width );
4930
                    if( width <= 1 || remainder.size() != 1 )
4931
                        remainder = remainder.substr( 1 );
4932
                    indent = _attr.indent;
4933
                }
4934
                else {
4935
                    pos = remainder.find_last_of( wrappableChars, width );
4936
                    if( pos != std::string::npos && pos > 0 ) {
4937
                        spliceLine( indent, remainder, pos );
4938
                        if( remainder[0] == ' ' )
4939
                            remainder = remainder.substr( 1 );
4940
                    }
4941
                    else {
4942
                        spliceLine( indent, remainder, width-1 );
4943
                        lines.back() += "-";
4944
                    }
4945
                    if( lines.size() == 1 )
4946
                        indent = _attr.indent;
4947
                    if( tabPos != std::string::npos )
4948
                        indent += tabPos;
4949
                }
4950
            }
4951
        }
4952
4953
        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4954
            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
4955
            _remainder = _remainder.substr( _pos );
4956
        }
4957
4958
        typedef std::vector<std::string>::const_iterator const_iterator;
4959
4960
        const_iterator begin() const { return lines.begin(); }
4961
        const_iterator end() const { return lines.end(); }
4962
        std::string const& last() const { return lines.back(); }
4963
        std::size_t size() const { return lines.size(); }
4964
        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
4965
        std::string toString() const {
4966
            std::ostringstream oss;
4967
            oss << *this;
4968
            return oss.str();
4969
        }
4970
4971
        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
4972
            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4973
                it != itEnd; ++it ) {
4974
                if( it != _text.begin() )
4975
                    _stream << "\n";
4976
                _stream << *it;
4977
            }
4978
            return _stream;
4979
        }
4980
4981
    private:
4982
        std::string str;
4983
        TextAttributes attr;
4984
        std::vector<std::string> lines;
4985
    };
4986
4987
} // end namespace Tbc
4988
4989
#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4990
} // end outer namespace
4991
#endif
4992
4993
#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4994
#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4995
4996
namespace Catch {
4997
    using Tbc::Text;
4998
    using Tbc::TextAttributes;
4999
}
5000
5001
// #included from: catch_console_colour.hpp
5002
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
5003
5004
namespace Catch {
5005
5006
    struct Colour {
5007
        enum Code {
5008
            None = 0,
5009
5010
            White,
5011
            Red,
5012
            Green,
5013
            Blue,
5014
            Cyan,
5015
            Yellow,
5016
            Grey,
5017
5018
            Bright = 0x10,
5019
5020
            BrightRed = Bright | Red,
5021
            BrightGreen = Bright | Green,
5022
            LightGrey = Bright | Grey,
5023
            BrightWhite = Bright | White,
5024
5025
            // By intention
5026
            FileName = LightGrey,
5027
            Warning = Yellow,
5028
            ResultError = BrightRed,
5029
            ResultSuccess = BrightGreen,
5030
            ResultExpectedFailure = Warning,
5031
5032
            Error = BrightRed,
5033
            Success = Green,
5034
5035
            OriginalExpression = Cyan,
5036
            ReconstructedExpression = Yellow,
5037
5038
            SecondaryText = LightGrey,
5039
            Headers = White
5040
        };
5041
5042
        // Use constructed object for RAII guard
5043
        Colour( Code _colourCode );
5044
        Colour( Colour const& other );
5045
        ~Colour();
5046
5047
        // Use static method for one-shot changes
5048
        static void use( Code _colourCode );
5049
5050
    private:
5051
        bool m_moved;
5052
    };
5053
5054
    inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
5055
5056
} // end namespace Catch
5057
5058
// #included from: catch_interfaces_reporter.h
5059
#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
5060
5061
#include <string>
5062
#include <ostream>
5063
#include <map>
5064
#include <assert.h>
5065
5066
namespace Catch
5067
{
5068
2
    struct ReporterConfig {
5069
        explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
5070
3
        :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
5071
5072
        ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
5073
        :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
5074
5075
        std::ostream& stream() const    { return *m_stream; }
5076
2
        Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
5077
5078
    private:
5079
        std::ostream* m_stream;
5080
        Ptr<IConfig const> m_fullConfig;
5081
    };
5082
5083
    struct ReporterPreferences {
5084
        ReporterPreferences()
5085
1
        : shouldRedirectStdOut( false )
5086
        {}
5087
5088
        bool shouldRedirectStdOut;
5089
    };
5090
5091
    template<typename T>
5092
6
    struct LazyStat : Option<T> {
5093
6
        LazyStat() : used( false ) {}
5094
        LazyStat& operator=( T const& _value ) {
5095
397
            Option<T>::operator=( _value );
5096
397
            used = false;
5097
            return *this;
5098
        }
5099
        void reset() {
5100
399
            Option<T>::reset();
5101
399
            used = false;
5102
        }
5103
        bool used;
5104
    };
5105
5106
9
    struct TestRunInfo {
5107
2
        TestRunInfo( std::string const& _name ) : name( _name ) {}
5108
        std::string name;
5109
    };
5110
12
    struct GroupInfo {
5111
        GroupInfo(  std::string const& _name,
5112
                    std::size_t _groupIndex,
5113
                    std::size_t _groupsCount )
5114
2
        :   name( _name ),
5115
            groupIndex( _groupIndex ),
5116
4
            groupsCounts( _groupsCount )
5117
        {}
5118
5119
        std::string name;
5120
        std::size_t groupIndex;
5121
        std::size_t groupsCounts;
5122
    };
5123
5124
    struct AssertionStats {
5125
1433002
        AssertionStats( AssertionResult const& _assertionResult,
5126
                        std::vector<MessageInfo> const& _infoMessages,
5127
                        Totals const& _totals )
5128
1433002
        :   assertionResult( _assertionResult ),
5129
            infoMessages( _infoMessages ),
5130
1433002
            totals( _totals )
5131
        {
5132
2866004
            if( assertionResult.hasMessage() ) {
5133
                // Copy message into messages list.
5134
                // !TBD This should have been done earlier, somewhere
5135
                MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
5136
                builder << assertionResult.getMessage();
5137
                builder.m_info.message = builder.m_stream.str();
5138
5139
                infoMessages.push_back( builder.m_info );
5140
            }
5141
1433002
        }
5142
        virtual ~AssertionStats();
5143
5144
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5145
        AssertionStats( AssertionStats const& )              = default;
5146
        AssertionStats( AssertionStats && )                  = default;
5147
        AssertionStats& operator = ( AssertionStats const& ) = default;
5148
        AssertionStats& operator = ( AssertionStats && )     = default;
5149
#  endif
5150
5151
        AssertionResult assertionResult;
5152
        std::vector<MessageInfo> infoMessages;
5153
        Totals totals;
5154
    };
5155
5156
    struct SectionStats {
5157
        SectionStats(   SectionInfo const& _sectionInfo,
5158
                        Counts const& _assertions,
5159
                        double _durationInSeconds,
5160
                        bool _missingAssertions )
5161
1167
        :   sectionInfo( _sectionInfo ),
5162
            assertions( _assertions ),
5163
            durationInSeconds( _durationInSeconds ),
5164

1167
            missingAssertions( _missingAssertions )
5165
        {}
5166
        virtual ~SectionStats();
5167
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5168
        SectionStats( SectionStats const& )              = default;
5169
        SectionStats( SectionStats && )                  = default;
5170
        SectionStats& operator = ( SectionStats const& ) = default;
5171
        SectionStats& operator = ( SectionStats && )     = default;
5172
#  endif
5173
5174
        SectionInfo sectionInfo;
5175
        Counts assertions;
5176
        double durationInSeconds;
5177
        bool missingAssertions;
5178
    };
5179
5180
    struct TestCaseStats {
5181
395
        TestCaseStats(  TestCaseInfo const& _testInfo,
5182
                        Totals const& _totals,
5183
                        std::string const& _stdOut,
5184
                        std::string const& _stdErr,
5185
                        bool _aborting )
5186
395
        : testInfo( _testInfo ),
5187
            totals( _totals ),
5188
            stdOut( _stdOut ),
5189
            stdErr( _stdErr ),
5190
1185
            aborting( _aborting )
5191
395
        {}
5192
        virtual ~TestCaseStats();
5193
5194
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5195
        TestCaseStats( TestCaseStats const& )              = default;
5196
        TestCaseStats( TestCaseStats && )                  = default;
5197
        TestCaseStats& operator = ( TestCaseStats const& ) = default;
5198
        TestCaseStats& operator = ( TestCaseStats && )     = default;
5199
#  endif
5200
5201
        TestCaseInfo testInfo;
5202
        Totals totals;
5203
        std::string stdOut;
5204
        std::string stdErr;
5205
        bool aborting;
5206
    };
5207
5208
    struct TestGroupStats {
5209
1
        TestGroupStats( GroupInfo const& _groupInfo,
5210
                        Totals const& _totals,
5211
                        bool _aborting )
5212
1
        :   groupInfo( _groupInfo ),
5213
            totals( _totals ),
5214
2
            aborting( _aborting )
5215
1
        {}
5216
        TestGroupStats( GroupInfo const& _groupInfo )
5217
        :   groupInfo( _groupInfo ),
5218
            aborting( false )
5219
        {}
5220
        virtual ~TestGroupStats();
5221
5222
#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5223
        TestGroupStats( TestGroupStats const& )              = default;
5224
        TestGroupStats( TestGroupStats && )                  = default;
5225
        TestGroupStats& operator = ( TestGroupStats const& ) = default;
5226
        TestGroupStats& operator = ( TestGroupStats && )     = default;
5227
#  endif
5228
5229
        GroupInfo groupInfo;
5230
        Totals totals;
5231
        bool aborting;
5232
    };
5233
5234
    struct TestRunStats {
5235
        TestRunStats(   TestRunInfo const& _runInfo,
5236
                        Totals const& _totals,
5237
                        bool _aborting )
5238
1
        :   runInfo( _runInfo ),
5239
            totals( _totals ),
5240
2
            aborting( _aborting )
5241
        {}
5242
        virtual ~TestRunStats();
5243
5244
#  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
5245
        TestRunStats( TestRunStats const& _other )
5246
        :   runInfo( _other.runInfo ),
5247
            totals( _other.totals ),
5248
            aborting( _other.aborting )
5249
        {}
5250
#  else
5251
        TestRunStats( TestRunStats const& )              = default;
5252
        TestRunStats( TestRunStats && )                  = default;
5253
        TestRunStats& operator = ( TestRunStats const& ) = default;
5254
        TestRunStats& operator = ( TestRunStats && )     = default;
5255
#  endif
5256
5257
        TestRunInfo runInfo;
5258
        Totals totals;
5259
        bool aborting;
5260
    };
5261
5262
    class MultipleReporters;
5263
5264
2
    struct IStreamingReporter : IShared {
5265
        virtual ~IStreamingReporter();
5266
5267
        // Implementing class must also provide the following static method:
5268
        // static std::string getDescription();
5269
5270
        virtual ReporterPreferences getPreferences() const = 0;
5271
5272
        virtual void noMatchingTestCases( std::string const& spec ) = 0;
5273
5274
        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5275
        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5276
5277
        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5278
        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5279
5280
        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5281
5282
        // The return value indicates if the messages buffer should be cleared:
5283
        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5284
5285
        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5286
        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5287
        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5288
        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5289
5290
        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5291
5292
        virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
5293
    };
5294
5295
8
    struct IReporterFactory : IShared {
5296
        virtual ~IReporterFactory();
5297
        virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
5298
        virtual std::string getDescription() const = 0;
5299
    };
5300
5301
    struct IReporterRegistry {
5302
        typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5303
        typedef std::vector<Ptr<IReporterFactory> > Listeners;
5304
5305
        virtual ~IReporterRegistry();
5306
        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
5307
        virtual FactoryMap const& getFactories() const = 0;
5308
        virtual Listeners const& getListeners() const = 0;
5309
    };
5310
5311
    Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
5312
5313
}
5314
5315
#include <limits>
5316
#include <algorithm>
5317
5318
namespace Catch {
5319
5320
    inline std::size_t listTests( Config const& config ) {
5321
5322
        TestSpec testSpec = config.testSpec();
5323
        if( config.testSpec().hasFilters() )
5324
            Catch::cout() << "Matching test cases:\n";
5325
        else {
5326
            Catch::cout() << "All available test cases:\n";
5327
            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5328
        }
5329
5330
        std::size_t matchedTests = 0;
5331
        TextAttributes nameAttr, tagsAttr;
5332
        nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5333
        tagsAttr.setIndent( 6 );
5334
5335
        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5336
        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5337
                it != itEnd;
5338
                ++it ) {
5339
            matchedTests++;
5340
            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5341
            Colour::Code colour = testCaseInfo.isHidden()
5342
                ? Colour::SecondaryText
5343
                : Colour::None;
5344
            Colour colourGuard( colour );
5345
5346
            Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
5347
            if( !testCaseInfo.tags.empty() )
5348
                Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5349
        }
5350
5351
        if( !config.testSpec().hasFilters() )
5352
            Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
5353
        else
5354
            Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
5355
        return matchedTests;
5356
    }
5357
5358
    inline std::size_t listTestsNamesOnly( Config const& config ) {
5359
        TestSpec testSpec = config.testSpec();
5360
        if( !config.testSpec().hasFilters() )
5361
            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5362
        std::size_t matchedTests = 0;
5363
        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5364
        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5365
                it != itEnd;
5366
                ++it ) {
5367
            matchedTests++;
5368
            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5369
            Catch::cout() << testCaseInfo.name << std::endl;
5370
        }
5371
        return matchedTests;
5372
    }
5373
5374
    struct TagInfo {
5375
        TagInfo() : count ( 0 ) {}
5376
        void add( std::string const& spelling ) {
5377
            ++count;
5378
            spellings.insert( spelling );
5379
        }
5380
        std::string all() const {
5381
            std::string out;
5382
            for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5383
                        it != itEnd;
5384
                        ++it )
5385
                out += "[" + *it + "]";
5386
            return out;
5387
        }
5388
        std::set<std::string> spellings;
5389
        std::size_t count;
5390
    };
5391
5392
    inline std::size_t listTags( Config const& config ) {
5393
        TestSpec testSpec = config.testSpec();
5394
        if( config.testSpec().hasFilters() )
5395
            Catch::cout() << "Tags for matching test cases:\n";
5396
        else {
5397
            Catch::cout() << "All available tags:\n";
5398
            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5399
        }
5400
5401
        std::map<std::string, TagInfo> tagCounts;
5402
5403
        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5404
        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5405
                it != itEnd;
5406
                ++it ) {
5407
            for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
5408
                                                        tagItEnd = it->getTestCaseInfo().tags.end();
5409
                    tagIt != tagItEnd;
5410
                    ++tagIt ) {
5411
                std::string tagName = *tagIt;
5412
                std::string lcaseTagName = toLower( tagName );
5413
                std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5414
                if( countIt == tagCounts.end() )
5415
                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5416
                countIt->second.add( tagName );
5417
            }
5418
        }
5419
5420
        for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5421
                                                            countItEnd = tagCounts.end();
5422
                countIt != countItEnd;
5423
                ++countIt ) {
5424
            std::ostringstream oss;
5425
            oss << "  " << std::setw(2) << countIt->second.count << "  ";
5426
            Text wrapper( countIt->second.all(), TextAttributes()
5427
                                                    .setInitialIndent( 0 )
5428
                                                    .setIndent( oss.str().size() )
5429
                                                    .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
5430
            Catch::cout() << oss.str() << wrapper << "\n";
5431
        }
5432
        Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
5433
        return tagCounts.size();
5434
    }
5435
5436
    inline std::size_t listReporters( Config const& /*config*/ ) {
5437
        Catch::cout() << "Available reporters:\n";
5438
        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
5439
        IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5440
        std::size_t maxNameLen = 0;
5441
        for(it = itBegin; it != itEnd; ++it )
5442
            maxNameLen = (std::max)( maxNameLen, it->first.size() );
5443
5444
        for(it = itBegin; it != itEnd; ++it ) {
5445
            Text wrapper( it->second->getDescription(), TextAttributes()
5446
                                                        .setInitialIndent( 0 )
5447
                                                        .setIndent( 7+maxNameLen )
5448
                                                        .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
5449
            Catch::cout() << "  "
5450
                    << it->first
5451
                    << ":"
5452
                    << std::string( maxNameLen - it->first.size() + 2, ' ' )
5453
                    << wrapper << "\n";
5454
        }
5455
        Catch::cout() << std::endl;
5456
        return factories.size();
5457
    }
5458
5459
1
    inline Option<std::size_t> list( Config const& config ) {
5460
1
        Option<std::size_t> listedCount;
5461
1
        if( config.listTests() )
5462
            listedCount = listedCount.valueOr(0) + listTests( config );
5463
1
        if( config.listTestNamesOnly() )
5464
            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
5465
1
        if( config.listTags() )
5466
            listedCount = listedCount.valueOr(0) + listTags( config );
5467
1
        if( config.listReporters() )
5468
            listedCount = listedCount.valueOr(0) + listReporters( config );
5469
1
        return listedCount;
5470
    }
5471
5472
} // end namespace Catch
5473
5474
// #included from: internal/catch_run_context.hpp
5475
#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
5476
5477
// #included from: catch_test_case_tracker.hpp
5478
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
5479
5480
#include <map>
5481
#include <string>
5482
#include <assert.h>
5483
#include <vector>
5484
5485
namespace Catch {
5486
namespace TestCaseTracking {
5487
5488
2402
    struct ITracker : SharedImpl<> {
5489
        virtual ~ITracker();
5490
5491
        // static queries
5492
        virtual std::string name() const = 0;
5493
5494
        // dynamic queries
5495
        virtual bool isComplete() const = 0; // Successfully completed or failed
5496
        virtual bool isSuccessfullyCompleted() const = 0;
5497
        virtual bool isOpen() const = 0; // Started but not complete
5498
        virtual bool hasChildren() const = 0;
5499
5500
        virtual ITracker& parent() = 0;
5501
5502
        // actions
5503
        virtual void close() = 0; // Successfully complete
5504
        virtual void fail() = 0;
5505
        virtual void markAsNeedingAnotherRun() = 0;
5506
5507
        virtual void addChild( Ptr<ITracker> const& child ) = 0;
5508
        virtual ITracker* findChild( std::string const& name ) = 0;
5509
        virtual void openChild() = 0;
5510
5511
        // Debug/ checking
5512
        virtual bool isSectionTracker() const = 0;
5513
        virtual bool isIndexTracker() const = 0;
5514
    };
5515
5516
2
    class TrackerContext {
5517
5518
        enum RunState {
5519
            NotStarted,
5520
            Executing,
5521
            CompletedCycle
5522
        };
5523
5524
        Ptr<ITracker> m_rootTracker;
5525
        ITracker* m_currentTracker;
5526
        RunState m_runState;
5527
5528
    public:
5529
5530
        static TrackerContext& instance() {
5531
            static TrackerContext s_instance;
5532
            return s_instance;
5533
        }
5534
5535
        TrackerContext()
5536
1
        :   m_currentTracker( CATCH_NULL ),
5537
2
            m_runState( NotStarted )
5538
        {}
5539
5540
        ITracker& startRun();
5541
5542
        void endRun() {
5543
            m_rootTracker.reset();
5544
            m_currentTracker = CATCH_NULL;
5545
            m_runState = NotStarted;
5546
        }
5547
5548
        void startCycle() {
5549
1512
            m_currentTracker = m_rootTracker.get();
5550
756
            m_runState = Executing;
5551
        }
5552
        void completeCycle() {
5553
1167
            m_runState = CompletedCycle;
5554
        }
5555
5556
        bool completedCycle() const {
5557
            return m_runState == CompletedCycle;
5558
        }
5559
        ITracker& currentTracker() {
5560
            return *m_currentTracker;
5561
        }
5562
        void setCurrentTracker( ITracker* tracker ) {
5563
2334
            m_currentTracker = tracker;
5564
        }
5565
    };
5566
5567
    class TrackerBase : public ITracker {
5568
    protected:
5569
        enum CycleState {
5570
            NotStarted,
5571
            Executing,
5572
            ExecutingChildren,
5573
            NeedsAnotherRun,
5574
            CompletedSuccessfully,
5575
            Failed
5576
        };
5577
164646
        class TrackerHasName {
5578
            std::string m_name;
5579
        public:
5580
18294
            TrackerHasName( std::string const& name ) : m_name( name ) {}
5581
193483
            bool operator ()( Ptr<ITracker> const& tracker ) {
5582
580449
                return tracker->name() == m_name;
5583
            }
5584
        };
5585
        typedef std::vector<Ptr<ITracker> > Children;
5586
        std::string m_name;
5587
        TrackerContext& m_ctx;
5588
        ITracker* m_parent;
5589
        Children m_children;
5590
        CycleState m_runState;
5591
    public:
5592
        TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
5593
1201
        :   m_name( name ),
5594
            m_ctx( ctx ),
5595
            m_parent( parent ),
5596
4804
            m_runState( NotStarted )
5597
        {}
5598
        virtual ~TrackerBase();
5599
5600
193483
        virtual std::string name() const CATCH_OVERRIDE {
5601
386966
            return m_name;
5602
        }
5603
9969
        virtual bool isComplete() const CATCH_OVERRIDE {
5604
9969
            return m_runState == CompletedSuccessfully || m_runState == Failed;
5605
        }
5606
756
        virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
5607
756
            return m_runState == CompletedSuccessfully;
5608
        }
5609
8391
        virtual bool isOpen() const CATCH_OVERRIDE {
5610

8391
            return m_runState != NotStarted && !isComplete();
5611
        }
5612
        virtual bool hasChildren() const CATCH_OVERRIDE {
5613
            return !m_children.empty();
5614
        }
5615
5616
806
        virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
5617
806
            m_children.push_back( child );
5618
806
        }
5619
5620
9147
        virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
5621
45735
            Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
5622
27441
            return( it != m_children.end() )
5623
17488
                ? it->get()
5624
9147
                : CATCH_NULL;
5625
        }
5626
        virtual ITracker& parent() CATCH_OVERRIDE {
5627
            assert( m_parent ); // Should always be non-null except for root
5628
            return *m_parent;
5629
        }
5630
5631
1578
        virtual void openChild() CATCH_OVERRIDE {
5632
1578
            if( m_runState != ExecutingChildren ) {
5633
806
                m_runState = ExecutingChildren;
5634
806
                if( m_parent )
5635
411
                    m_parent->openChild();
5636
            }
5637
1578
        }
5638
5639
        virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
5640
        virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
5641
5642
        void open() {
5643
1167
            m_runState = Executing;
5644
1167
            moveToThis();
5645
1167
            if( m_parent )
5646
1167
                m_parent->openChild();
5647
        }
5648
5649
1167
        virtual void close() CATCH_OVERRIDE {
5650
5651
            // Close any still open children (e.g. generators)
5652
1167
            while( &m_ctx.currentTracker() != this )
5653
                m_ctx.currentTracker().close();
5654
5655

1167
            switch( m_runState ) {
5656
                case NotStarted:
5657
                case CompletedSuccessfully:
5658
                case Failed:
5659
                    throw std::logic_error( "Illogical state" );
5660
5661
                case NeedsAnotherRun:
5662
                    break;;
5663
5664
                case Executing:
5665
756
                    m_runState = CompletedSuccessfully;
5666
756
                    break;
5667
                case ExecutingChildren:
5668

1644
                    if( m_children.empty() || m_children.back()->isComplete() )
5669
50
                        m_runState = CompletedSuccessfully;
5670
                    break;
5671
5672
                default:
5673
                    throw std::logic_error( "Unexpected state" );
5674
            }
5675
1167
            moveToParent();
5676
1167
            m_ctx.completeCycle();
5677
1167
        }
5678
        virtual void fail() CATCH_OVERRIDE {
5679
            m_runState = Failed;
5680
            if( m_parent )
5681
                m_parent->markAsNeedingAnotherRun();
5682
            moveToParent();
5683
            m_ctx.completeCycle();
5684
        }
5685
        virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
5686
            m_runState = NeedsAnotherRun;
5687
        }
5688
    private:
5689
        void moveToParent() {
5690

1167
            assert( m_parent );
5691
2334
            m_ctx.setCurrentTracker( m_parent );
5692
        }
5693
        void moveToThis() {
5694
2334
            m_ctx.setCurrentTracker( this );
5695
        }
5696
    };
5697
5698
    class SectionTracker : public TrackerBase {
5699
    public:
5700
        SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
5701
2402
        :   TrackerBase( name, ctx, parent )
5702
        {}
5703
        virtual ~SectionTracker();
5704
5705
8341
        virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
5706
5707
9147
        static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
5708
9147
            SectionTracker* section = CATCH_NULL;
5709
5710
9147
            ITracker& currentTracker = ctx.currentTracker();
5711
9147
            if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5712
                assert( childTracker );
5713
8341
                assert( childTracker->isSectionTracker() );
5714
                section = static_cast<SectionTracker*>( childTracker );
5715
            }
5716
            else {
5717
1612
                section = new SectionTracker( name, ctx, &currentTracker );
5718
2418
                currentTracker.addChild( section );
5719
            }
5720

9147
            if( !ctx.completedCycle() && !section->isComplete() ) {
5721
5722
1167
                section->open();
5723
            }
5724
9147
            return *section;
5725
        }
5726
    };
5727
5728
    class IndexTracker : public TrackerBase {
5729
        int m_size;
5730
        int m_index;
5731
    public:
5732
        IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
5733
        :   TrackerBase( name, ctx, parent ),
5734
            m_size( size ),
5735
            m_index( -1 )
5736
        {}
5737
        virtual ~IndexTracker();
5738
5739
        virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
5740
5741
        static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
5742
            IndexTracker* tracker = CATCH_NULL;
5743
5744
            ITracker& currentTracker = ctx.currentTracker();
5745
            if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5746
                assert( childTracker );
5747
                assert( childTracker->isIndexTracker() );
5748
                tracker = static_cast<IndexTracker*>( childTracker );
5749
            }
5750
            else {
5751
                tracker = new IndexTracker( name, ctx, &currentTracker, size );
5752
                currentTracker.addChild( tracker );
5753
            }
5754
5755
            if( !ctx.completedCycle() && !tracker->isComplete() ) {
5756
                if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
5757
                    tracker->moveNext();
5758
                tracker->open();
5759
            }
5760
5761
            return *tracker;
5762
        }
5763
5764
        int index() const { return m_index; }
5765
5766
        void moveNext() {
5767
            m_index++;
5768
            m_children.clear();
5769
        }
5770
5771
        virtual void close() CATCH_OVERRIDE {
5772
            TrackerBase::close();
5773
            if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
5774
                m_runState = Executing;
5775
        }
5776
    };
5777
5778
395
    inline ITracker& TrackerContext::startRun() {
5779
2370
        m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
5780
395
        m_currentTracker = CATCH_NULL;
5781
395
        m_runState = Executing;
5782
790
        return *m_rootTracker;
5783
    }
5784
5785
} // namespace TestCaseTracking
5786
5787
using TestCaseTracking::ITracker;
5788
using TestCaseTracking::TrackerContext;
5789
using TestCaseTracking::SectionTracker;
5790
using TestCaseTracking::IndexTracker;
5791
5792
} // namespace Catch
5793
5794
// #included from: catch_fatal_condition.hpp
5795
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
5796
5797
namespace Catch {
5798
5799
    // Report the error condition then exit the process
5800
    inline void fatal( std::string const& message, int exitCode ) {
5801
        IContext& context = Catch::getCurrentContext();
5802
        IResultCapture* resultCapture = context.getResultCapture();
5803
        resultCapture->handleFatalErrorCondition( message );
5804
5805
		if( Catch::alwaysTrue() ) // avoids "no return" warnings
5806
            exit( exitCode );
5807
    }
5808
5809
} // namespace Catch
5810
5811
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
5812
5813
namespace Catch {
5814
5815
    struct FatalConditionHandler {
5816
		void reset() {}
5817
	};
5818
5819
} // namespace Catch
5820
5821
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
5822
5823
#include <signal.h>
5824
5825
namespace Catch {
5826
5827
    struct SignalDefs { int id; const char* name; };
5828
    extern SignalDefs signalDefs[];
5829
    SignalDefs signalDefs[] = {
5830
            { SIGINT,  "SIGINT - Terminal interrupt signal" },
5831
            { SIGILL,  "SIGILL - Illegal instruction signal" },
5832
            { SIGFPE,  "SIGFPE - Floating point error signal" },
5833
            { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
5834
            { SIGTERM, "SIGTERM - Termination request signal" },
5835
            { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
5836
        };
5837
5838
    struct FatalConditionHandler {
5839
5840
        static void handleSignal( int sig ) {
5841
            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5842
                if( sig == signalDefs[i].id )
5843
                    fatal( signalDefs[i].name, -sig );
5844
            fatal( "<unknown signal>", -sig );
5845
        }
5846
5847
756
        FatalConditionHandler() : m_isSet( true ) {
5848
5292
            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5849
4536
                signal( signalDefs[i].id, handleSignal );
5850
        }
5851
        ~FatalConditionHandler() {
5852
756
            reset();
5853
        }
5854
1512
        void reset() {
5855
1512
            if( m_isSet ) {
5856
9828
                for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5857
4536
                    signal( signalDefs[i].id, SIG_DFL );
5858
756
                m_isSet = false;
5859
            }
5860
1512
        }
5861
5862
        bool m_isSet;
5863
    };
5864
5865
} // namespace Catch
5866
5867
#endif // not Windows
5868
5869
#include <set>
5870
#include <string>
5871
5872
namespace Catch {
5873
5874
    class StreamRedirect {
5875
5876
    public:
5877
        StreamRedirect( std::ostream& stream, std::string& targetString )
5878
        :   m_stream( stream ),
5879
            m_prevBuf( stream.rdbuf() ),
5880
            m_targetString( targetString )
5881
        {
5882
            stream.rdbuf( m_oss.rdbuf() );
5883
        }
5884
5885
        ~StreamRedirect() {
5886
            m_targetString += m_oss.str();
5887
            m_stream.rdbuf( m_prevBuf );
5888
        }
5889
5890
    private:
5891
        std::ostream& m_stream;
5892
        std::streambuf* m_prevBuf;
5893
        std::ostringstream m_oss;
5894
        std::string& m_targetString;
5895
    };
5896
5897
    ///////////////////////////////////////////////////////////////////////////
5898
5899
    class RunContext : public IResultCapture, public IRunner {
5900
5901
        RunContext( RunContext const& );
5902
        void operator =( RunContext const& );
5903
5904
    public:
5905
5906
1
        explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
5907
3
        :   m_runInfo( _config->name() ),
5908
1
            m_context( getCurrentMutableContext() ),
5909
            m_activeTestCase( CATCH_NULL ),
5910
            m_config( _config ),
5911
13
            m_reporter( reporter )
5912
        {
5913
1
            m_context.setRunner( this );
5914
1
            m_context.setConfig( m_config );
5915
1
            m_context.setResultCapture( this );
5916
2
            m_reporter->testRunStarting( m_runInfo );
5917
1
        }
5918
5919
8
        virtual ~RunContext() {
5920
5
            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
5921
1
        }
5922
5923
1
        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
5924
4
            m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
5925
1
        }
5926
1
        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
5927

5
            m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
5928
1
        }
5929
5930
395
        Totals runTest( TestCase const& testCase ) {
5931
395
            Totals prevTotals = m_totals;
5932
5933
790
            std::string redirectedCout;
5934
790
            std::string redirectedCerr;
5935
5936
790
            TestCaseInfo testInfo = testCase.getTestCaseInfo();
5937
5938
790
            m_reporter->testCaseStarting( testInfo );
5939
5940
395
            m_activeTestCase = &testCase;
5941
5942
395
            do {
5943
395
                m_trackerContext.startRun();
5944
756
                do {
5945
1512
                    m_trackerContext.startCycle();
5946
756
                    m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
5947
756
                    runCurrentTest( redirectedCout, redirectedCerr );
5948
                }
5949


756
                while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
5950
            }
5951
            // !TBD: deprecated - this will be replaced by indexed trackers
5952


395
            while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
5953
5954
395
            Totals deltaTotals = m_totals.delta( prevTotals );
5955

395
            if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
5956
                deltaTotals.assertions.failed++;
5957
                deltaTotals.testCases.passed--;
5958
                deltaTotals.testCases.failed++;
5959
            }
5960
790
            m_totals.testCases += deltaTotals.testCases;
5961
1580
            m_reporter->testCaseEnded( TestCaseStats(   testInfo,
5962
                                                        deltaTotals,
5963
                                                        redirectedCout,
5964
                                                        redirectedCerr,
5965

790
                                                        aborting() ) );
5966
5967
395
            m_activeTestCase = CATCH_NULL;
5968
395
            m_testCaseTracker = CATCH_NULL;
5969
5970
395
            return deltaTotals;
5971
        }
5972
5973
        Ptr<IConfig const> config() const {
5974
            return m_config;
5975
        }
5976
5977
    private: // IResultCapture
5978
5979
1433002
        virtual void assertionEnded( AssertionResult const& result ) {
5980
1433002
            if( result.getResultType() == ResultWas::Ok ) {
5981
1433002
                m_totals.assertions.passed++;
5982
            }
5983
            else if( !result.isOk() ) {
5984
                m_totals.assertions.failed++;
5985
            }
5986
5987

2866004
            if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
5988
                m_messages.clear();
5989
5990
            // Reset working state
5991

10031014
            m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
5992
1433002
            m_lastResult = result;
5993
1433002
        }
5994
5995
8391
        virtual bool sectionStarted (
5996
            SectionInfo const& sectionInfo,
5997
            Counts& assertions
5998
        )
5999
        {
6000
16782
            std::ostringstream oss;
6001
25173
            oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
6002
6003
16782
            ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
6004

8391
            if( !sectionTracker.isOpen() )
6005
                return false;
6006
822
            m_activeSections.push_back( &sectionTracker );
6007
6008
822
            m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
6009
6010
822
            m_reporter->sectionStarting( sectionInfo );
6011
6012
411
            assertions = m_totals.assertions;
6013
6014
411
            return true;
6015
        }
6016
1167
        bool testForMissingAssertions( Counts& assertions ) {
6017
1167
            if( assertions.total() != 0 )
6018
                return false;
6019
296
            if( !m_config->warnAboutMissingAssertions() )
6020
                return false;
6021
            if( m_trackerContext.currentTracker().hasChildren() )
6022
                return false;
6023
            m_totals.assertions.failed++;
6024
            assertions.failed++;
6025
            return true;
6026
        }
6027
6028
411
        virtual void sectionEnded( SectionEndInfo const& endInfo ) {
6029
822
            Counts assertions = m_totals.assertions - endInfo.prevAssertions;
6030
411
            bool missingAssertions = testForMissingAssertions( assertions );
6031
6032
822
            if( !m_activeSections.empty() ) {
6033
822
                m_activeSections.back()->close();
6034
411
                m_activeSections.pop_back();
6035
            }
6036
6037
1644
            m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
6038
822
            m_messages.clear();
6039
411
        }
6040
6041
        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
6042
            if( m_unfinishedSections.empty() )
6043
                m_activeSections.back()->fail();
6044
            else
6045
                m_activeSections.back()->close();
6046
            m_activeSections.pop_back();
6047
6048
            m_unfinishedSections.push_back( endInfo );
6049
        }
6050
6051
        virtual void pushScopedMessage( MessageInfo const& message ) {
6052
            m_messages.push_back( message );
6053
        }
6054
6055
        virtual void popScopedMessage( MessageInfo const& message ) {
6056
            m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
6057
        }
6058
6059
395
        virtual std::string getCurrentTestName() const {
6060
395
            return m_activeTestCase
6061
395
                ? m_activeTestCase->getTestCaseInfo().name
6062
790
                : "";
6063
        }
6064
6065
        virtual const AssertionResult* getLastResult() const {
6066
            return &m_lastResult;
6067
        }
6068
6069
        virtual void handleFatalErrorCondition( std::string const& message ) {
6070
            ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
6071
            resultBuilder.setResultType( ResultWas::FatalErrorCondition );
6072
            resultBuilder << message;
6073
// stack
6074
#ifdef HAVE_EXECINFO
6075
            {
6076
            void *array[15];
6077
            const int size = static_cast<int>(backtrace(array, 15));
6078
            char **strings = backtrace_symbols(array, size);
6079
            for (int i = 0; i < size; i++)
6080
                resultBuilder << strings[i];
6081
            free(strings);
6082
            }
6083
#endif  // HAVE_EXECINFO
6084
// stack
6085
6086
            resultBuilder.captureExpression();
6087
6088
            handleUnfinishedSections();
6089
6090
            // Recreate section for test case (as we will lose the one that was in scope)
6091
            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6092
            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6093
6094
            Counts assertions;
6095
            assertions.failed = 1;
6096
            SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
6097
            m_reporter->sectionEnded( testCaseSectionStats );
6098
6099
            TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
6100
6101
            Totals deltaTotals;
6102
            deltaTotals.testCases.failed = 1;
6103
            m_reporter->testCaseEnded( TestCaseStats(   testInfo,
6104
                                                        deltaTotals,
6105
                                                        "",
6106
                                                        "",
6107
                                                        false ) );
6108
            m_totals.testCases.failed++;
6109
            testGroupEnded( "", m_totals, 1, 1 );
6110
            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
6111
        }
6112
6113
    public:
6114
        // !TBD We need to do this another way!
6115
757
        bool aborting() const {
6116
2306
            return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
6117
        }
6118
6119
    private:
6120
6121
756
        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
6122
1512
            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6123
1512
            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6124
1512
            m_reporter->sectionStarting( testCaseSection );
6125
756
            Counts prevAssertions = m_totals.assertions;
6126
756
            double duration = 0;
6127
            try {
6128

5292
                m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
6129
6130
1512
                seedRng( *m_config );
6131
6132
756
                Timer timer;
6133
756
                timer.start();
6134

1512
                if( m_reporter->getPreferences().shouldRedirectStdOut ) {
6135
                    StreamRedirect coutRedir( Catch::cout(), redirectedCout );
6136
                    StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
6137
                    invokeActiveTestCase();
6138
                }
6139
                else {
6140
756
                    invokeActiveTestCase();
6141
                }
6142
756
                duration = timer.getElapsedSeconds();
6143
            }
6144
            catch( TestFailureException& ) {
6145
                // This just means the test was aborted due to failure
6146
            }
6147
            catch(...) {
6148
                makeUnexpectedResultBuilder().useActiveException();
6149
            }
6150
756
            m_testCaseTracker->close();
6151
756
            handleUnfinishedSections();
6152
1512
            m_messages.clear();
6153
6154
1512
            Counts assertions = m_totals.assertions - prevAssertions;
6155
756
            bool missingAssertions = testForMissingAssertions( assertions );
6156
6157
756
            if( testCaseInfo.okToFail() ) {
6158
                std::swap( assertions.failedButOk, assertions.failed );
6159
                m_totals.assertions.failed -= assertions.failedButOk;
6160
                m_totals.assertions.failedButOk += assertions.failedButOk;
6161
            }
6162
6163
2268
            SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
6164
1512
            m_reporter->sectionEnded( testCaseSectionStats );
6165
756
        }
6166
6167
756
        void invokeActiveTestCase() {
6168
1512
            FatalConditionHandler fatalConditionHandler; // Handle signals
6169
1512
            m_activeTestCase->invoke();
6170
756
            fatalConditionHandler.reset();
6171
756
        }
6172
6173
    private:
6174
6175
        ResultBuilder makeUnexpectedResultBuilder() const {
6176
            return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),
6177
                                    m_lastAssertionInfo.lineInfo,
6178
                                    m_lastAssertionInfo.capturedExpression.c_str(),
6179
                                    m_lastAssertionInfo.resultDisposition );
6180
        }
6181
6182
756
        void handleUnfinishedSections() {
6183
            // If sections ended prematurely due to an exception we stored their
6184
            // infos here so we can tear them down outside the unwind process.
6185
3024
            for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
6186
2268
                        itEnd = m_unfinishedSections.rend();
6187
                    it != itEnd;
6188
                    ++it )
6189
                sectionEnded( *it );
6190
1512
            m_unfinishedSections.clear();
6191
756
        }
6192
6193
        TestRunInfo m_runInfo;
6194
        IMutableContext& m_context;
6195
        TestCase const* m_activeTestCase;
6196
        ITracker* m_testCaseTracker;
6197
        ITracker* m_currentSectionTracker;
6198
        AssertionResult m_lastResult;
6199
6200
        Ptr<IConfig const> m_config;
6201
        Totals m_totals;
6202
        Ptr<IStreamingReporter> m_reporter;
6203
        std::vector<MessageInfo> m_messages;
6204
        AssertionInfo m_lastAssertionInfo;
6205
        std::vector<SectionEndInfo> m_unfinishedSections;
6206
        std::vector<ITracker*> m_activeSections;
6207
        TrackerContext m_trackerContext;
6208
    };
6209
6210
1441804
    IResultCapture& getResultCapture() {
6211
1441804
        if( IResultCapture* capture = getCurrentContext().getResultCapture() )
6212
1441804
            return *capture;
6213
        else
6214
            throw std::logic_error( "No result capture instance" );
6215
    }
6216
6217
} // end namespace Catch
6218
6219
// #included from: internal/catch_version.h
6220
#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
6221
6222
namespace Catch {
6223
6224
    // Versioning information
6225
2
    struct Version {
6226
        Version(    unsigned int _majorVersion,
6227
                    unsigned int _minorVersion,
6228
                    unsigned int _patchNumber,
6229
                    std::string const& _branchName,
6230
                    unsigned int _buildNumber );
6231
6232
        unsigned int const majorVersion;
6233
        unsigned int const minorVersion;
6234
        unsigned int const patchNumber;
6235
6236
        // buildNumber is only used if branchName is not null
6237
        std::string const branchName;
6238
        unsigned int const buildNumber;
6239
6240
        friend std::ostream& operator << ( std::ostream& os, Version const& version );
6241
6242
    private:
6243
        void operator=( Version const& );
6244
    };
6245
6246
    extern Version libraryVersion;
6247
}
6248
6249
#include <fstream>
6250
#include <stdlib.h>
6251
#include <limits>
6252
6253
namespace Catch {
6254
6255
1
    Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
6256
5
        Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
6257
1
        if( !reporter ) {
6258
            std::ostringstream oss;
6259
            oss << "No reporter registered with name: '" << reporterName << "'";
6260
            throw std::domain_error( oss.str() );
6261
        }
6262
1
        return reporter;
6263
    }
6264
6265
1
    Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
6266
3
        std::vector<std::string> reporters = config->getReporterNames();
6267
1
        if( reporters.empty() )
6268
5
            reporters.push_back( "console" );
6269
6270
1
        Ptr<IStreamingReporter> reporter;
6271
6
        for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
6272
                it != itEnd;
6273
                ++it )
6274

3
            reporter = addReporter( reporter, createReporter( *it, config ) );
6275
1
        return reporter;
6276
    }
6277
1
    Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
6278
2
        IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
6279
5
        for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
6280
                it != itEnd;
6281
                ++it )
6282
            reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
6283
2
        return reporters;
6284
    }
6285
6286
1
    Totals runTests( Ptr<Config> const& config ) {
6287
6288
3
        Ptr<IConfig const> iconfig = config.get();
6289
6290
2
        Ptr<IStreamingReporter> reporter = makeReporter( config );
6291

3
        reporter = addListeners( iconfig, reporter );
6292
6293
2
        RunContext context( iconfig, reporter );
6294
6295
1
        Totals totals;
6296
6297

2
        context.testGroupStarting( config->name(), 1, 1 );
6298
6299
3
        TestSpec testSpec = config->testSpec();
6300
1
        if( !testSpec.hasFilters() )
6301

9
            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
6302
6303
1
        std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
6304
399
        for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
6305
                it != itEnd;
6306
                ++it ) {
6307


790
            if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
6308
790
                totals += context.runTest( *it );
6309
            else
6310
                reporter->skipTest( *it );
6311
        }
6312
6313

2
        context.testGroupEnded( iconfig->name(), totals, 1, 1 );
6314
1
        return totals;
6315
    }
6316
6317
    void applyFilenamesAsTags( IConfig const& config ) {
6318
        std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
6319
        for(std::size_t i = 0; i < tests.size(); ++i ) {
6320
            TestCase& test = const_cast<TestCase&>( tests[i] );
6321
            std::set<std::string> tags = test.tags;
6322
6323
            std::string filename = test.lineInfo.file;
6324
            std::string::size_type lastSlash = filename.find_last_of( "\\/" );
6325
            if( lastSlash != std::string::npos )
6326
                filename = filename.substr( lastSlash+1 );
6327
6328
            std::string::size_type lastDot = filename.find_last_of( "." );
6329
            if( lastDot != std::string::npos )
6330
                filename = filename.substr( 0, lastDot );
6331
6332
            tags.insert( "#" + filename );
6333
            setTags( test, tags );
6334
        }
6335
    }
6336
6337
    class Session : NonCopyable {
6338
        static bool alreadyInstantiated;
6339
6340
    public:
6341
6342
        struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
6343
6344
1
        Session()
6345
5
        : m_cli( makeCommandLineParser() ) {
6346
1
            if( alreadyInstantiated ) {
6347
                std::string msg = "Only one instance of Catch::Session can ever be used";
6348
                Catch::cerr() << msg << std::endl;
6349
                throw std::logic_error( msg );
6350
            }
6351
1
            alreadyInstantiated = true;
6352
1
        }
6353
3
        ~Session() {
6354
1
            Catch::cleanUp();
6355
1
        }
6356
6357
        void showHelp( std::string const& processName ) {
6358
            Catch::cout() << "\nCatch v" << libraryVersion << "\n";
6359
6360
            m_cli.usage( Catch::cout(), processName );
6361
            Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
6362
        }
6363
6364
1
        int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
6365
            try {
6366
2
                m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
6367

2
                m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
6368
1
                if( m_configData.showHelp )
6369
                    showHelp( m_configData.processName );
6370
2
                m_config.reset();
6371
            }
6372
            catch( std::exception& ex ) {
6373
                {
6374
                    Colour colourGuard( Colour::Red );
6375
                    Catch::cerr()
6376
                        << "\nError(s) in input:\n"
6377
                        << Text( ex.what(), TextAttributes().setIndent(2) )
6378
                        << "\n\n";
6379
                }
6380
                m_cli.usage( Catch::cout(), m_configData.processName );
6381
                return (std::numeric_limits<int>::max)();
6382
            }
6383
1
            return 0;
6384
        }
6385
6386
        void useConfigData( ConfigData const& _configData ) {
6387
            m_configData = _configData;
6388
            m_config.reset();
6389
        }
6390
6391
1
        int run( int argc, char const* const* const argv ) {
6392
6393
1
            int returnCode = applyCommandLine( argc, argv );
6394
1
            if( returnCode == 0 )
6395
1
                returnCode = run();
6396
1
            return returnCode;
6397
        }
6398
6399
1
        int run() {
6400
1
            if( m_configData.showHelp )
6401
                return 0;
6402
6403
            try
6404
            {
6405
1
                config(); // Force config to be constructed
6406
6407
2
                seedRng( *m_config );
6408
6409
1
                if( m_configData.filenamesAsTags )
6410
                    applyFilenamesAsTags( *m_config );
6411
6412
                // Handle list request
6413

3
                if( Option<std::size_t> listed = list( config() ) )
6414
                    return static_cast<int>( *listed );
6415
6416

1
                return static_cast<int>( runTests( m_config ).assertions.failed );
6417
            }
6418
            catch( std::exception& ex ) {
6419
                Catch::cerr() << ex.what() << std::endl;
6420
                return (std::numeric_limits<int>::max)();
6421
            }
6422
        }
6423
6424
        Clara::CommandLine<ConfigData> const& cli() const {
6425
            return m_cli;
6426
        }
6427
        std::vector<Clara::Parser::Token> const& unusedTokens() const {
6428
            return m_unusedTokens;
6429
        }
6430
        ConfigData& configData() {
6431
            return m_configData;
6432
        }
6433
2
        Config& config() {
6434
4
            if( !m_config )
6435
1
                m_config = new Config( m_configData );
6436
4
            return *m_config;
6437
        }
6438
    private:
6439
        Clara::CommandLine<ConfigData> m_cli;
6440
        std::vector<Clara::Parser::Token> m_unusedTokens;
6441
        ConfigData m_configData;
6442
        Ptr<Config> m_config;
6443
    };
6444
6445
    bool Session::alreadyInstantiated = false;
6446
6447
} // end namespace Catch
6448
6449
// #included from: catch_registry_hub.hpp
6450
#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
6451
6452
// #included from: catch_test_case_registry_impl.hpp
6453
#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
6454
6455
#include <vector>
6456
#include <set>
6457
#include <sstream>
6458
#include <iostream>
6459
#include <algorithm>
6460
6461
namespace Catch {
6462
6463
    struct LexSort {
6464
        bool operator() (TestCase i,TestCase j) const { return (i<j);}
6465
    };
6466
    struct RandomNumberGenerator {
6467
        int operator()( int n ) const { return std::rand() % n; }
6468
    };
6469
6470
1
    inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
6471
6472
1
        std::vector<TestCase> sorted = unsortedTestCases;
6473
6474

1
        switch( config.runOrder() ) {
6475
            case RunTests::InLexicographicalOrder:
6476
                std::sort( sorted.begin(), sorted.end(), LexSort() );
6477
                break;
6478
            case RunTests::InRandomOrder:
6479
                {
6480
                    seedRng( config );
6481
6482
                    RandomNumberGenerator rng;
6483
                    std::random_shuffle( sorted.begin(), sorted.end(), rng );
6484
                }
6485
                break;
6486
            case RunTests::InDeclarationOrder:
6487
                // already in declaration order
6488
                break;
6489
        }
6490
1
        return sorted;
6491
    }
6492
395
    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
6493

395
        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
6494
    }
6495
6496
1
    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
6497
2
        std::set<TestCase> seenFunctions;
6498
399
        for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
6499
            it != itEnd;
6500
            ++it ) {
6501
790
            std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
6502
395
            if( !prev.second ){
6503
                Catch::cerr()
6504
                << Colour( Colour::Red )
6505
                << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
6506
                << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
6507
                << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
6508
                exit(1);
6509
            }
6510
        }
6511
1
    }
6512
6513
    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
6514
        std::vector<TestCase> filtered;
6515
        filtered.reserve( testCases.size() );
6516
        for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
6517
                it != itEnd;
6518
                ++it )
6519
            if( matchTest( *it, testSpec, config ) )
6520
                filtered.push_back( *it );
6521
        return filtered;
6522
    }
6523
1
    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
6524
1
        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
6525
    }
6526
6527
    class TestRegistry : public ITestCaseRegistry {
6528
    public:
6529
1
        TestRegistry()
6530
1
        :   m_currentSortOrder( RunTests::InDeclarationOrder ),
6531
3
            m_unnamedCount( 0 )
6532
1
        {}
6533
        virtual ~TestRegistry();
6534
6535
395
        virtual void registerTest( TestCase const& testCase ) {
6536
1185
            std::string name = testCase.getTestCaseInfo().name;
6537
395
            if( name == "" ) {
6538
                std::ostringstream oss;
6539
                oss << "Anonymous test case " << ++m_unnamedCount;
6540
                return registerTest( testCase.withName( oss.str() ) );
6541
            }
6542
395
            m_functions.push_back( testCase );
6543
        }
6544
6545
        virtual std::vector<TestCase> const& getAllTests() const {
6546
            return m_functions;
6547
        }
6548
1
        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
6549
2
            if( m_sortedFunctions.empty() )
6550
1
                enforceNoDuplicateTestCases( m_functions );
6551
6552

2
            if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
6553
2
                m_sortedFunctions = sortTests( config, m_functions );
6554
1
                m_currentSortOrder = config.runOrder();
6555
            }
6556
1
            return m_sortedFunctions;
6557
        }
6558
6559
    private:
6560
        std::vector<TestCase> m_functions;
6561
        mutable RunTests::InWhatOrder m_currentSortOrder;
6562
        mutable std::vector<TestCase> m_sortedFunctions;
6563
        size_t m_unnamedCount;
6564
        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
6565
    };
6566
6567
    ///////////////////////////////////////////////////////////////////////////
6568
6569
    class FreeFunctionTestCase : public SharedImpl<ITestCase> {
6570
    public:
6571
6572
790
        FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
6573
6574
756
        virtual void invoke() const {
6575
756
            m_fun();
6576
756
        }
6577
6578
    private:
6579
        virtual ~FreeFunctionTestCase();
6580
6581
        TestFunction m_fun;
6582
    };
6583
6584
395
    inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
6585
395
        std::string className = classOrQualifiedMethodName;
6586

1580
        if( startsWith( className, "&" ) )
6587
        {
6588
            std::size_t lastColons = className.rfind( "::" );
6589
            std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
6590
            if( penultimateColons == std::string::npos )
6591
                penultimateColons = 1;
6592
            className = className.substr( penultimateColons, lastColons-penultimateColons );
6593
        }
6594
395
        return className;
6595
    }
6596
6597
395
    void registerTestCase
6598
        (   ITestCase* testCase,
6599
            char const* classOrQualifiedMethodName,
6600
            NameAndDesc const& nameAndDesc,
6601
            SourceLineInfo const& lineInfo ) {
6602
6603
        getMutableRegistryHub().registerTest
6604
            ( makeTestCase
6605

3555
                (   testCase,
6606

1975
                    extractClassName( classOrQualifiedMethodName ),
6607
395
                    nameAndDesc.name,
6608
395
                    nameAndDesc.description,
6609
790
                    lineInfo ) );
6610
395
    }
6611
395
    void registerTestCaseFunction
6612
        (   TestFunction function,
6613
            SourceLineInfo const& lineInfo,
6614
            NameAndDesc const& nameAndDesc ) {
6615
790
        registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
6616
395
    }
6617
6618
    ///////////////////////////////////////////////////////////////////////////
6619
6620
395
    AutoReg::AutoReg
6621
        (   TestFunction function,
6622
            SourceLineInfo const& lineInfo,
6623
            NameAndDesc const& nameAndDesc ) {
6624
395
        registerTestCaseFunction( function, lineInfo, nameAndDesc );
6625
395
    }
6626
6627
395
    AutoReg::~AutoReg() {}
6628
6629
} // end namespace Catch
6630
6631
// #included from: catch_reporter_registry.hpp
6632
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
6633
6634
#include <map>
6635
6636
namespace Catch {
6637
6638
3
    class ReporterRegistry : public IReporterRegistry {
6639
6640
    public:
6641
6642
2
        virtual ~ReporterRegistry() CATCH_OVERRIDE {}
6643
6644
1
        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
6645
2
            FactoryMap::const_iterator it =  m_factories.find( name );
6646
2
            if( it == m_factories.end() )
6647
                return CATCH_NULL;
6648
4
            return it->second->create( ReporterConfig( config ) );
6649
        }
6650
6651
4
        void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
6652
8
            m_factories.insert( std::make_pair( name, factory ) );
6653
4
        }
6654
        void registerListener( Ptr<IReporterFactory> const& factory ) {
6655
            m_listeners.push_back( factory );
6656
        }
6657
6658
        virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
6659
            return m_factories;
6660
        }
6661
1
        virtual Listeners const& getListeners() const CATCH_OVERRIDE {
6662
1
            return m_listeners;
6663
        }
6664
6665
    private:
6666
        FactoryMap m_factories;
6667
        Listeners m_listeners;
6668
    };
6669
}
6670
6671
// #included from: catch_exception_translator_registry.hpp
6672
#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
6673
6674
#ifdef __OBJC__
6675
#import "Foundation/Foundation.h"
6676
#endif
6677
6678
namespace Catch {
6679
6680
2
    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
6681
    public:
6682
3
        ~ExceptionTranslatorRegistry() {
6683
2
            deleteAll( m_translators );
6684
1
        }
6685
6686
        virtual void registerTranslator( const IExceptionTranslator* translator ) {
6687
            m_translators.push_back( translator );
6688
        }
6689
6690
31
        virtual std::string translateActiveException() const {
6691
            try {
6692
#ifdef __OBJC__
6693
                // In Objective-C try objective-c exceptions first
6694
                @try {
6695
                    return tryTranslators();
6696
                }
6697
                @catch (NSException *exception) {
6698
                    return Catch::toString( [exception description] );
6699
                }
6700
#else
6701

31
                return tryTranslators();
6702
#endif
6703
            }
6704
            catch( TestFailureException& ) {
6705
                throw;
6706
            }
6707
            catch( std::exception& ex ) {
6708
                return ex.what();
6709
            }
6710
            catch( std::string& msg ) {
6711
                return msg;
6712
            }
6713
            catch( const char* msg ) {
6714
                return msg;
6715
            }
6716
62
            catch(...) {
6717
93
                return "Unknown exception";
6718
            }
6719
        }
6720
6721
31
        std::string tryTranslators() const {
6722
62
            if( m_translators.empty() )
6723
31
                throw;
6724
            else
6725
                return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
6726
        }
6727
6728
    private:
6729
        std::vector<const IExceptionTranslator*> m_translators;
6730
    };
6731
}
6732
6733
namespace Catch {
6734
6735
    namespace {
6736
6737
3
        class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
6738
6739
            RegistryHub( RegistryHub const& );
6740
            void operator=( RegistryHub const& );
6741
6742
        public: // IRegistryHub
6743
3
            RegistryHub() {
6744
1
            }
6745
2
            virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
6746
2
                return m_reporterRegistry;
6747
            }
6748
1
            virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
6749
1
                return m_testCaseRegistry;
6750
            }
6751
31
            virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
6752
31
                return m_exceptionTranslatorRegistry;
6753
            }
6754
6755
        public: // IMutableRegistryHub
6756
4
            virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6757
4
                m_reporterRegistry.registerReporter( name, factory );
6758
4
            }
6759
            virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6760
                m_reporterRegistry.registerListener( factory );
6761
            }
6762
395
            virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
6763
395
                m_testCaseRegistry.registerTest( testInfo );
6764
395
            }
6765
            virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
6766
                m_exceptionTranslatorRegistry.registerTranslator( translator );
6767
            }
6768
6769
        private:
6770
            TestRegistry m_testCaseRegistry;
6771
            ReporterRegistry m_reporterRegistry;
6772
            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
6773
        };
6774
6775
        // Single, global, instance
6776
435
        inline RegistryHub*& getTheRegistryHub() {
6777
            static RegistryHub* theRegistryHub = CATCH_NULL;
6778
435
            if( !theRegistryHub )
6779
1
                theRegistryHub = new RegistryHub();
6780
435
            return theRegistryHub;
6781
        }
6782
    }
6783
6784
    IRegistryHub& getRegistryHub() {
6785
34
        return *getTheRegistryHub();
6786
    }
6787
    IMutableRegistryHub& getMutableRegistryHub() {
6788
399
        return *getTheRegistryHub();
6789
    }
6790
1
    void cleanUp() {
6791
1
        delete getTheRegistryHub();
6792
1
        getTheRegistryHub() = CATCH_NULL;
6793
        cleanUpContext();
6794
1
    }
6795
31
    std::string translateActiveException() {
6796
31
        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
6797
    }
6798
6799
} // end namespace Catch
6800
6801
// #included from: catch_notimplemented_exception.hpp
6802
#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
6803
6804
#include <ostream>
6805
6806
namespace Catch {
6807
6808
    NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
6809
    :   m_lineInfo( lineInfo ) {
6810
        std::ostringstream oss;
6811
        oss << lineInfo << ": function ";
6812
        oss << "not implemented";
6813
        m_what = oss.str();
6814
    }
6815
6816
    const char* NotImplementedException::what() const CATCH_NOEXCEPT {
6817
        return m_what.c_str();
6818
    }
6819
6820
} // end namespace Catch
6821
6822
// #included from: catch_context_impl.hpp
6823
#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
6824
6825
// #included from: catch_stream.hpp
6826
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
6827
6828
#include <stdexcept>
6829
#include <cstdio>
6830
#include <iostream>
6831
6832
namespace Catch {
6833
6834
    template<typename WriterF, size_t bufferSize=256>
6835
    class StreamBufImpl : public StreamBufBase {
6836
        char data[bufferSize];
6837
        WriterF m_writer;
6838
6839
    public:
6840
        StreamBufImpl() {
6841
            setp( data, data + sizeof(data) );
6842
        }
6843
6844
        ~StreamBufImpl() CATCH_NOEXCEPT {
6845
            sync();
6846
        }
6847
6848
    private:
6849
        int overflow( int c ) {
6850
            sync();
6851
6852
            if( c != EOF ) {
6853
                if( pbase() == epptr() )
6854
                    m_writer( std::string( 1, static_cast<char>( c ) ) );
6855
                else
6856
                    sputc( static_cast<char>( c ) );
6857
            }
6858
            return 0;
6859
        }
6860
6861
        int sync() {
6862
            if( pbase() != pptr() ) {
6863
                m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6864
                setp( pbase(), epptr() );
6865
            }
6866
            return 0;
6867
        }
6868
    };
6869
6870
    ///////////////////////////////////////////////////////////////////////////
6871
6872
    FileStream::FileStream( std::string const& filename ) {
6873
        m_ofs.open( filename.c_str() );
6874
        if( m_ofs.fail() ) {
6875
            std::ostringstream oss;
6876
            oss << "Unable to open file: '" << filename << "'";
6877
            throw std::domain_error( oss.str() );
6878
        }
6879
    }
6880
6881
    std::ostream& FileStream::stream() const {
6882
        return m_ofs;
6883
    }
6884
6885
    struct OutputDebugWriter {
6886
6887
        void operator()( std::string const&str ) {
6888
            writeToDebugConsole( str );
6889
        }
6890
    };
6891
6892
    DebugOutStream::DebugOutStream()
6893
    :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
6894
        m_os( m_streamBuf.get() )
6895
    {}
6896
6897
    std::ostream& DebugOutStream::stream() const {
6898
        return m_os;
6899
    }
6900
6901
    // Store the streambuf from cout up-front because
6902
    // cout may get redirected when running tests
6903
1
    CoutStream::CoutStream()
6904
1
    :   m_os( Catch::cout().rdbuf() )
6905
    {}
6906
6907
1
    std::ostream& CoutStream::stream() const {
6908
1
        return m_os;
6909
    }
6910
6911
#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
6912
    std::ostream& cout() {
6913
        return std::cout;
6914
    }
6915
    std::ostream& cerr() {
6916
        return std::cerr;
6917
    }
6918
#endif
6919
}
6920
6921
namespace Catch {
6922
6923
5
    class Context : public IMutableContext {
6924
6925
4
        Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
6926
        Context( Context const& );
6927
        void operator=( Context const& );
6928
6929
    public: // IContext
6930
1442199
        virtual IResultCapture* getResultCapture() {
6931
1442199
            return m_resultCapture;
6932
        }
6933
        virtual IRunner* getRunner() {
6934
            return m_runner;
6935
        }
6936
        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
6937
            return getGeneratorsForCurrentTest()
6938
            .getGeneratorInfo( fileInfo, totalSize )
6939
            .getCurrentIndex();
6940
        }
6941
395
        virtual bool advanceGeneratorsForCurrentTest() {
6942
395
            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6943

395
            return generators && generators->moveNext();
6944
        }
6945
6946
164079
        virtual Ptr<IConfig const> getConfig() const {
6947
328158
            return m_config;
6948
        }
6949
6950
    public: // IMutableContext
6951
1
        virtual void setResultCapture( IResultCapture* resultCapture ) {
6952
1
            m_resultCapture = resultCapture;
6953
1
        }
6954
1
        virtual void setRunner( IRunner* runner ) {
6955
1
            m_runner = runner;
6956
1
        }
6957
1
        virtual void setConfig( Ptr<IConfig const> const& config ) {
6958
1
            m_config = config;
6959
1
        }
6960
6961
        friend IMutableContext& getCurrentMutableContext();
6962
6963
    private:
6964
395
        IGeneratorsForTest* findGeneratorsForCurrentTest() {
6965
790
            std::string testName = getResultCapture()->getCurrentTestName();
6966
6967
            std::map<std::string, IGeneratorsForTest*>::const_iterator it =
6968
1185
                m_generatorsByTestName.find( testName );
6969
1185
            return it != m_generatorsByTestName.end()
6970
395
                ? it->second
6971
395
                : CATCH_NULL;
6972
        }
6973
6974
        IGeneratorsForTest& getGeneratorsForCurrentTest() {
6975
            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6976
            if( !generators ) {
6977
                std::string testName = getResultCapture()->getCurrentTestName();
6978
                generators = createGeneratorsForTest();
6979
                m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
6980
            }
6981
            return *generators;
6982
        }
6983
6984
    private:
6985
        Ptr<IConfig const> m_config;
6986
        IRunner* m_runner;
6987
        IResultCapture* m_resultCapture;
6988
        std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
6989
    };
6990
6991
    namespace {
6992
        Context* currentContext = CATCH_NULL;
6993
    }
6994
1606279
    IMutableContext& getCurrentMutableContext() {
6995
1606279
        if( !currentContext )
6996
2
            currentContext = new Context();
6997
1606279
        return *currentContext;
6998
    }
6999
    IContext& getCurrentContext() {
7000

1606278
        return getCurrentMutableContext();
7001
    }
7002
7003
    void cleanUpContext() {
7004

1
        delete currentContext;
7005
1
        currentContext = CATCH_NULL;
7006
    }
7007
}
7008
7009
// #included from: catch_console_colour_impl.hpp
7010
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
7011
7012
namespace Catch {
7013
    namespace {
7014
7015
        struct IColourImpl {
7016
            virtual ~IColourImpl() {}
7017
            virtual void use( Colour::Code _colourCode ) = 0;
7018
        };
7019
7020
1
        struct NoColourImpl : IColourImpl {
7021
8
            void use( Colour::Code ) {}
7022
7023
1
            static IColourImpl* instance() {
7024

1
                static NoColourImpl s_instance;
7025
1
                return &s_instance;
7026
            }
7027
        };
7028
7029
    } // anon namespace
7030
} // namespace Catch
7031
7032
#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7033
#   ifdef CATCH_PLATFORM_WINDOWS
7034
#       define CATCH_CONFIG_COLOUR_WINDOWS
7035
#   else
7036
#       define CATCH_CONFIG_COLOUR_ANSI
7037
#   endif
7038
#endif
7039
7040
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
7041
7042
#ifndef NOMINMAX
7043
#define NOMINMAX
7044
#endif
7045
7046
#ifdef __AFXDLL
7047
#include <AfxWin.h>
7048
#else
7049
#include <windows.h>
7050
#endif
7051
7052
namespace Catch {
7053
namespace {
7054
7055
    class Win32ColourImpl : public IColourImpl {
7056
    public:
7057
        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7058
        {
7059
            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7060
            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7061
            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7062
            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7063
        }
7064
7065
        virtual void use( Colour::Code _colourCode ) {
7066
            switch( _colourCode ) {
7067
                case Colour::None:      return setTextAttribute( originalForegroundAttributes );
7068
                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7069
                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
7070
                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
7071
                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
7072
                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7073
                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7074
                case Colour::Grey:      return setTextAttribute( 0 );
7075
7076
                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
7077
                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7078
                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7079
                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7080
7081
                case Colour::Bright: throw std::logic_error( "not a colour" );
7082
            }
7083
        }
7084
7085
    private:
7086
        void setTextAttribute( WORD _textAttribute ) {
7087
            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7088
        }
7089
        HANDLE stdoutHandle;
7090
        WORD originalForegroundAttributes;
7091
        WORD originalBackgroundAttributes;
7092
    };
7093
7094
    IColourImpl* platformColourInstance() {
7095
        static Win32ColourImpl s_instance;
7096
7097
        Ptr<IConfig const> config = getCurrentContext().getConfig();
7098
        UseColour::YesOrNo colourMode = config
7099
            ? config->useColour()
7100
            : UseColour::Auto;
7101
        if( colourMode == UseColour::Auto )
7102
            colourMode = !isDebuggerActive()
7103
                ? UseColour::Yes
7104
                : UseColour::No;
7105
        return colourMode == UseColour::Yes
7106
            ? &s_instance
7107
            : NoColourImpl::instance();
7108
    }
7109
7110
} // end anon namespace
7111
} // end namespace Catch
7112
7113
#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
7114
7115
#include <unistd.h>
7116
7117
namespace Catch {
7118
namespace {
7119
7120
    // use POSIX/ ANSI console terminal codes
7121
    // Thanks to Adam Strzelecki for original contribution
7122
    // (http://github.com/nanoant)
7123
    // https://github.com/philsquared/Catch/pull/131
7124
    class PosixColourImpl : public IColourImpl {
7125
    public:
7126
        virtual void use( Colour::Code _colourCode ) {
7127
            switch( _colourCode ) {
7128
                case Colour::None:
7129
                case Colour::White:     return setColour( "[0m" );
7130
                case Colour::Red:       return setColour( "[0;31m" );
7131
                case Colour::Green:     return setColour( "[0;32m" );
7132
                case Colour::Blue:      return setColour( "[0:34m" );
7133
                case Colour::Cyan:      return setColour( "[0;36m" );
7134
                case Colour::Yellow:    return setColour( "[0;33m" );
7135
                case Colour::Grey:      return setColour( "[1;30m" );
7136
7137
                case Colour::LightGrey:     return setColour( "[0;37m" );
7138
                case Colour::BrightRed:     return setColour( "[1;31m" );
7139
                case Colour::BrightGreen:   return setColour( "[1;32m" );
7140
                case Colour::BrightWhite:   return setColour( "[1;37m" );
7141
7142
                case Colour::Bright: throw std::logic_error( "not a colour" );
7143
            }
7144
        }
7145
        static IColourImpl* instance() {
7146
            static PosixColourImpl s_instance;
7147
            return &s_instance;
7148
        }
7149
7150
    private:
7151
        void setColour( const char* _escapeCode ) {
7152
            Catch::cout() << '\033' << _escapeCode;
7153
        }
7154
    };
7155
7156
1
    IColourImpl* platformColourInstance() {
7157
2
        Ptr<IConfig const> config = getCurrentContext().getConfig();
7158
        UseColour::YesOrNo colourMode = config
7159

1
            ? config->useColour()
7160
2
            : UseColour::Auto;
7161
1
        if( colourMode == UseColour::Auto )
7162
1
            colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
7163
                ? UseColour::Yes
7164
                : UseColour::No;
7165
        return colourMode == UseColour::Yes
7166
1
            ? PosixColourImpl::instance()
7167
2
            : NoColourImpl::instance();
7168
    }
7169
7170
} // end anon namespace
7171
} // end namespace Catch
7172
7173
#else  // not Windows or ANSI ///////////////////////////////////////////////
7174
7175
namespace Catch {
7176
7177
    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
7178
7179
} // end namespace Catch
7180
7181
#endif // Windows/ ANSI/ None
7182
7183
namespace Catch {
7184
7185






4
    Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
7186
    Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
7187
4
    Colour::~Colour(){ if( !m_moved ) use( None ); }
7188
7189
8
    void Colour::use( Code _colourCode ) {
7190

8
        static IColourImpl* impl = platformColourInstance();
7191
8
        impl->use( _colourCode );
7192
8
    }
7193
7194
} // end namespace Catch
7195
7196
// #included from: catch_generators_impl.hpp
7197
#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
7198
7199
#include <vector>
7200
#include <string>
7201
#include <map>
7202
7203
namespace Catch {
7204
7205
    struct GeneratorInfo : IGeneratorInfo {
7206
7207
        GeneratorInfo( std::size_t size )
7208
        :   m_size( size ),
7209
            m_currentIndex( 0 )
7210
        {}
7211
7212
        bool moveNext() {
7213
            if( ++m_currentIndex == m_size ) {
7214
                m_currentIndex = 0;
7215
                return false;
7216
            }
7217
            return true;
7218
        }
7219
7220
        std::size_t getCurrentIndex() const {
7221
            return m_currentIndex;
7222
        }
7223
7224
        std::size_t m_size;
7225
        std::size_t m_currentIndex;
7226
    };
7227
7228
    ///////////////////////////////////////////////////////////////////////////
7229
7230
    class GeneratorsForTest : public IGeneratorsForTest {
7231
7232
    public:
7233
        ~GeneratorsForTest() {
7234
            deleteAll( m_generatorsInOrder );
7235
        }
7236
7237
        IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
7238
            std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
7239
            if( it == m_generatorsByName.end() ) {
7240
                IGeneratorInfo* info = new GeneratorInfo( size );
7241
                m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
7242
                m_generatorsInOrder.push_back( info );
7243
                return *info;
7244
            }
7245
            return *it->second;
7246
        }
7247
7248
        bool moveNext() {
7249
            std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
7250
            std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
7251
            for(; it != itEnd; ++it ) {
7252
                if( (*it)->moveNext() )
7253
                    return true;
7254
            }
7255
            return false;
7256
        }
7257
7258
    private:
7259
        std::map<std::string, IGeneratorInfo*> m_generatorsByName;
7260
        std::vector<IGeneratorInfo*> m_generatorsInOrder;
7261
    };
7262
7263
    IGeneratorsForTest* createGeneratorsForTest()
7264
    {
7265
        return new GeneratorsForTest();
7266
    }
7267
7268
} // end namespace Catch
7269
7270
// #included from: catch_assertionresult.hpp
7271
#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
7272
7273
namespace Catch {
7274
7275
2866760
    AssertionInfo::AssertionInfo(   std::string const& _macroName,
7276
                                    SourceLineInfo const& _lineInfo,
7277
                                    std::string const& _capturedExpression,
7278
2866760
                                    ResultDisposition::Flags _resultDisposition )
7279
    :   macroName( _macroName ),
7280
        lineInfo( _lineInfo ),
7281
        capturedExpression( _capturedExpression ),
7282
11467040
        resultDisposition( _resultDisposition )
7283
2866760
    {}
7284
7285
3
    AssertionResult::AssertionResult() {}
7286
7287
1433002
    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
7288
    :   m_info( info ),
7289
1433002
        m_resultData( data )
7290
1433002
    {}
7291
7292
2866005
    AssertionResult::~AssertionResult() {}
7293
7294
    // Result was a success
7295
    bool AssertionResult::succeeded() const {
7296
        return Catch::isOk( m_resultData.resultType );
7297
    }
7298
7299
    // Result was a success, or failure is suppressed
7300
    bool AssertionResult::isOk() const {
7301









5732008
        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
7302
    }
7303
7304
    ResultWas::OfType AssertionResult::getResultType() const {
7305
2866004
        return m_resultData.resultType;
7306
    }
7307
7308
    bool AssertionResult::hasExpression() const {
7309
        return !m_info.capturedExpression.empty();
7310
    }
7311
7312
    bool AssertionResult::hasMessage() const {
7313
2866004
        return !m_resultData.message.empty();
7314
    }
7315
7316
    std::string AssertionResult::getExpression() const {
7317
        if( isFalseTest( m_info.resultDisposition ) )
7318
            return "!" + m_info.capturedExpression;
7319
        else
7320
            return m_info.capturedExpression;
7321
    }
7322
    std::string AssertionResult::getExpressionInMacro() const {
7323
        if( m_info.macroName.empty() )
7324
            return m_info.capturedExpression;
7325
        else
7326
            return m_info.macroName + "( " + m_info.capturedExpression + " )";
7327
    }
7328
7329
    bool AssertionResult::hasExpandedExpression() const {
7330
        return hasExpression() && getExpandedExpression() != getExpression();
7331
    }
7332
7333
    std::string AssertionResult::getExpandedExpression() const {
7334
        return m_resultData.reconstructedExpression;
7335
    }
7336
7337
    std::string AssertionResult::getMessage() const {
7338
        return m_resultData.message;
7339
    }
7340
    SourceLineInfo AssertionResult::getSourceInfo() const {
7341
        return m_info.lineInfo;
7342
    }
7343
7344
    std::string AssertionResult::getTestMacroName() const {
7345
        return m_info.macroName;
7346
    }
7347
7348
} // end namespace Catch
7349
7350
// #included from: catch_test_case_info.hpp
7351
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
7352
7353
namespace Catch {
7354
7355
    inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
7356
        if( startsWith( tag, "." ) ||
7357
            tag == "hide" ||
7358
            tag == "!hide" )
7359
            return TestCaseInfo::IsHidden;
7360
        else if( tag == "!throws" )
7361
            return TestCaseInfo::Throws;
7362
        else if( tag == "!shouldfail" )
7363
            return TestCaseInfo::ShouldFail;
7364
        else if( tag == "!mayfail" )
7365
            return TestCaseInfo::MayFail;
7366
        else
7367
            return TestCaseInfo::None;
7368
    }
7369
    inline bool isReservedTag( std::string const& tag ) {
7370
        return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
7371
    }
7372
    inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
7373
        if( isReservedTag( tag ) ) {
7374
            {
7375
                Colour colourGuard( Colour::Red );
7376
                Catch::cerr()
7377
                    << "Tag name [" << tag << "] not allowed.\n"
7378
                    << "Tag names starting with non alpha-numeric characters are reserved\n";
7379
            }
7380
            {
7381
                Colour colourGuard( Colour::FileName );
7382
                Catch::cerr() << _lineInfo << std::endl;
7383
            }
7384
            exit(1);
7385
        }
7386
    }
7387
7388
395
    TestCase makeTestCase(  ITestCase* _testCase,
7389
                            std::string const& _className,
7390
                            std::string const& _name,
7391
                            std::string const& _descOrTags,
7392
                            SourceLineInfo const& _lineInfo )
7393
    {
7394
1580
        bool isHidden( startsWith( _name, "./" ) ); // Legacy support
7395
7396
        // Parse out tags
7397
790
        std::set<std::string> tags;
7398
1580
        std::string desc, tag;
7399
395
        bool inTag = false;
7400
847
        for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
7401
452
            char c = _descOrTags[i];
7402
452
            if( !inTag ) {
7403
452
                if( c == '[' )
7404
                    inTag = true;
7405
                else
7406
452
                    desc += c;
7407
            }
7408
            else {
7409
                if( c == ']' ) {
7410
                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
7411
                    if( prop == TestCaseInfo::IsHidden )
7412
                        isHidden = true;
7413
                    else if( prop == TestCaseInfo::None )
7414
                        enforceNotReservedTag( tag, _lineInfo );
7415
7416
                    tags.insert( tag );
7417
                    tag.clear();
7418
                    inTag = false;
7419
                }
7420
                else
7421
                    tag += c;
7422
            }
7423
        }
7424
395
        if( isHidden ) {
7425
            tags.insert( "hide" );
7426
            tags.insert( "." );
7427
        }
7428
7429
790
        TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
7430
790
        return TestCase( _testCase, info );
7431
    }
7432
7433
395
    void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
7434
    {
7435
790
        testCaseInfo.tags = tags;
7436
790
        testCaseInfo.lcaseTags.clear();
7437
7438
790
        std::ostringstream oss;
7439
790
        for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
7440
            oss << "[" << *it << "]";
7441
            std::string lcaseTag = toLower( *it );
7442
            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
7443
            testCaseInfo.lcaseTags.insert( lcaseTag );
7444
        }
7445
790
        testCaseInfo.tagsAsString = oss.str();
7446
395
    }
7447
7448
395
    TestCaseInfo::TestCaseInfo( std::string const& _name,
7449
                                std::string const& _className,
7450
                                std::string const& _description,
7451
                                std::set<std::string> const& _tags,
7452
395
                                SourceLineInfo const& _lineInfo )
7453
    :   name( _name ),
7454
        className( _className ),
7455
        description( _description ),
7456
        lineInfo( _lineInfo ),
7457
3160
        properties( None )
7458
    {
7459
395
        setTags( *this, _tags );
7460
395
    }
7461
7462
3276
    TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
7463
    :   name( other.name ),
7464
        className( other.className ),
7465
        description( other.description ),
7466
        tags( other.tags ),
7467
        lcaseTags( other.lcaseTags ),
7468
        tagsAsString( other.tagsAsString ),
7469
        lineInfo( other.lineInfo ),
7470
26208
        properties( other.properties )
7471
3276
    {}
7472
7473
    bool TestCaseInfo::isHidden() const {
7474
        return ( properties & IsHidden ) != 0;
7475
    }
7476
    bool TestCaseInfo::throws() const {
7477
        return ( properties & Throws ) != 0;
7478
    }
7479
    bool TestCaseInfo::okToFail() const {
7480
756
        return ( properties & (ShouldFail | MayFail ) ) != 0;
7481
    }
7482
    bool TestCaseInfo::expectedToFail() const {
7483
395
        return ( properties & (ShouldFail ) ) != 0;
7484
    }
7485
7486
790
    TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
7487
7488
1696
    TestCase::TestCase( TestCase const& other )
7489
    :   TestCaseInfo( other ),
7490
3392
        test( other.test )
7491
1696
    {}
7492
7493
    TestCase TestCase::withName( std::string const& _newName ) const {
7494
        TestCase other( *this );
7495
        other.name = _newName;
7496
        return other;
7497
    }
7498
7499
    void TestCase::swap( TestCase& other ) {
7500
        test.swap( other.test );
7501
        name.swap( other.name );
7502
        className.swap( other.className );
7503
        description.swap( other.description );
7504
        tags.swap( other.tags );
7505
        lcaseTags.swap( other.lcaseTags );
7506
        tagsAsString.swap( other.tagsAsString );
7507
        std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
7508
        std::swap( lineInfo, other.lineInfo );
7509
    }
7510
7511
    void TestCase::invoke() const {
7512
1512
        test->invoke();
7513
    }
7514
7515
    bool TestCase::operator == ( TestCase const& other ) const {
7516
        return  test.get() == other.test.get() &&
7517
                name == other.name &&
7518
                className == other.className;
7519
    }
7520
7521
    bool TestCase::operator < ( TestCase const& other ) const {
7522
8520
        return name < other.name;
7523
    }
7524
    TestCase& TestCase::operator = ( TestCase const& other ) {
7525
        TestCase temp( other );
7526
        swap( temp );
7527
        return *this;
7528
    }
7529
7530
    TestCaseInfo const& TestCase::getTestCaseInfo() const
7531
    {
7532
1151
        return *this;
7533
    }
7534
7535
} // end namespace Catch
7536
7537
// #included from: catch_version.hpp
7538
#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
7539
7540
namespace Catch {
7541
7542
    Version::Version
7543
        (   unsigned int _majorVersion,
7544
            unsigned int _minorVersion,
7545
            unsigned int _patchNumber,
7546
            std::string const& _branchName,
7547
1
            unsigned int _buildNumber )
7548
    :   majorVersion( _majorVersion ),
7549
        minorVersion( _minorVersion ),
7550
        patchNumber( _patchNumber ),
7551
        branchName( _branchName ),
7552
2
        buildNumber( _buildNumber )
7553
    {}
7554
7555
    std::ostream& operator << ( std::ostream& os, Version const& version ) {
7556
        os  << version.majorVersion << "."
7557
            << version.minorVersion << "."
7558
            << version.patchNumber;
7559
7560
        if( !version.branchName.empty() ) {
7561
            os  << "-" << version.branchName
7562
                << "." << version.buildNumber;
7563
        }
7564
        return os;
7565
    }
7566
7567
5
    Version libraryVersion( 1, 5, 1, "", 0 );
7568
7569
}
7570
7571
// #included from: catch_message.hpp
7572
#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
7573
7574
namespace Catch {
7575
7576
    MessageInfo::MessageInfo(   std::string const& _macroName,
7577
                                SourceLineInfo const& _lineInfo,
7578
                                ResultWas::OfType _type )
7579
    :   macroName( _macroName ),
7580
        lineInfo( _lineInfo ),
7581
        type( _type ),
7582
        sequence( ++globalCount )
7583
    {}
7584
7585
    // This may need protecting if threading support is added
7586
    unsigned int MessageInfo::globalCount = 0;
7587
7588
    ////////////////////////////////////////////////////////////////////////////
7589
7590
    ScopedMessage::ScopedMessage( MessageBuilder const& builder )
7591
    : m_info( builder.m_info )
7592
    {
7593
        m_info.message = builder.m_stream.str();
7594
        getResultCapture().pushScopedMessage( m_info );
7595
    }
7596
    ScopedMessage::ScopedMessage( ScopedMessage const& other )
7597
    : m_info( other.m_info )
7598
    {}
7599
7600
    ScopedMessage::~ScopedMessage() {
7601
        getResultCapture().popScopedMessage( m_info );
7602
    }
7603
7604
} // end namespace Catch
7605
7606
// #included from: catch_legacy_reporter_adapter.hpp
7607
#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
7608
7609
// #included from: catch_legacy_reporter_adapter.h
7610
#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
7611
7612
namespace Catch
7613
{
7614
    // Deprecated
7615
    struct IReporter : IShared {
7616
        virtual ~IReporter();
7617
7618
        virtual bool shouldRedirectStdout() const = 0;
7619
7620
        virtual void StartTesting() = 0;
7621
        virtual void EndTesting( Totals const& totals ) = 0;
7622
        virtual void StartGroup( std::string const& groupName ) = 0;
7623
        virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
7624
        virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
7625
        virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
7626
        virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
7627
        virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
7628
        virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
7629
        virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
7630
        virtual void Aborted() = 0;
7631
        virtual void Result( AssertionResult const& result ) = 0;
7632
    };
7633
7634
    class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
7635
    {
7636
    public:
7637
        LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
7638
        virtual ~LegacyReporterAdapter();
7639
7640
        virtual ReporterPreferences getPreferences() const;
7641
        virtual void noMatchingTestCases( std::string const& );
7642
        virtual void testRunStarting( TestRunInfo const& );
7643
        virtual void testGroupStarting( GroupInfo const& groupInfo );
7644
        virtual void testCaseStarting( TestCaseInfo const& testInfo );
7645
        virtual void sectionStarting( SectionInfo const& sectionInfo );
7646
        virtual void assertionStarting( AssertionInfo const& );
7647
        virtual bool assertionEnded( AssertionStats const& assertionStats );
7648
        virtual void sectionEnded( SectionStats const& sectionStats );
7649
        virtual void testCaseEnded( TestCaseStats const& testCaseStats );
7650
        virtual void testGroupEnded( TestGroupStats const& testGroupStats );
7651
        virtual void testRunEnded( TestRunStats const& testRunStats );
7652
        virtual void skipTest( TestCaseInfo const& );
7653
7654
    private:
7655
        Ptr<IReporter> m_legacyReporter;
7656
    };
7657
}
7658
7659
namespace Catch
7660
{
7661
    LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
7662
    :   m_legacyReporter( legacyReporter )
7663
    {}
7664
    LegacyReporterAdapter::~LegacyReporterAdapter() {}
7665
7666
    ReporterPreferences LegacyReporterAdapter::getPreferences() const {
7667
        ReporterPreferences prefs;
7668
        prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
7669
        return prefs;
7670
    }
7671
7672
    void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
7673
    void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
7674
        m_legacyReporter->StartTesting();
7675
    }
7676
    void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
7677
        m_legacyReporter->StartGroup( groupInfo.name );
7678
    }
7679
    void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
7680
        m_legacyReporter->StartTestCase( testInfo );
7681
    }
7682
    void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
7683
        m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
7684
    }
7685
    void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
7686
        // Not on legacy interface
7687
    }
7688
7689
    bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
7690
        if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
7691
            for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
7692
                    it != itEnd;
7693
                    ++it ) {
7694
                if( it->type == ResultWas::Info ) {
7695
                    ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
7696
                    rb << it->message;
7697
                    rb.setResultType( ResultWas::Info );
7698
                    AssertionResult result = rb.build();
7699
                    m_legacyReporter->Result( result );
7700
                }
7701
            }
7702
        }
7703
        m_legacyReporter->Result( assertionStats.assertionResult );
7704
        return true;
7705
    }
7706
    void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
7707
        if( sectionStats.missingAssertions )
7708
            m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
7709
        m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
7710
    }
7711
    void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
7712
        m_legacyReporter->EndTestCase
7713
            (   testCaseStats.testInfo,
7714
                testCaseStats.totals,
7715
                testCaseStats.stdOut,
7716
                testCaseStats.stdErr );
7717
    }
7718
    void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
7719
        if( testGroupStats.aborting )
7720
            m_legacyReporter->Aborted();
7721
        m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
7722
    }
7723
    void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
7724
        m_legacyReporter->EndTesting( testRunStats.totals );
7725
    }
7726
    void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
7727
    }
7728
}
7729
7730
// #included from: catch_timer.hpp
7731
7732
#ifdef __clang__
7733
#pragma clang diagnostic push
7734
#pragma clang diagnostic ignored "-Wc++11-long-long"
7735
#endif
7736
7737
#ifdef CATCH_PLATFORM_WINDOWS
7738
#include <windows.h>
7739
#else
7740
#include <sys/time.h>
7741
#endif
7742
7743
namespace Catch {
7744
7745
    namespace {
7746
#ifdef CATCH_PLATFORM_WINDOWS
7747
        uint64_t getCurrentTicks() {
7748
            static uint64_t hz=0, hzo=0;
7749
            if (!hz) {
7750
                QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
7751
                QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
7752
            }
7753
            uint64_t t;
7754
            QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
7755
            return ((t-hzo)*1000000)/hz;
7756
        }
7757
#else
7758
        uint64_t getCurrentTicks() {
7759
            timeval t;
7760
10314
            gettimeofday(&t,CATCH_NULL);
7761
10314
            return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
7762
        }
7763
#endif
7764
    }
7765
7766
    void Timer::start() {
7767
9147
        m_ticks = getCurrentTicks();
7768
    }
7769
    unsigned int Timer::getElapsedMicroseconds() const {
7770
1167
        return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
7771
    }
7772
    unsigned int Timer::getElapsedMilliseconds() const {
7773
        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
7774
    }
7775
1167
    double Timer::getElapsedSeconds() const {
7776
1167
        return getElapsedMicroseconds()/1000000.0;
7777
    }
7778
7779
} // namespace Catch
7780
7781
#ifdef __clang__
7782
#pragma clang diagnostic pop
7783
#endif
7784
// #included from: catch_common.hpp
7785
#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
7786
7787
namespace Catch {
7788
7789
791
    bool startsWith( std::string const& s, std::string const& prefix ) {
7790

1186
        return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
7791
    }
7792
    bool endsWith( std::string const& s, std::string const& suffix ) {
7793
        return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
7794
    }
7795
    bool contains( std::string const& s, std::string const& infix ) {
7796
        return s.find( infix ) != std::string::npos;
7797
    }
7798
1
    void toLowerInPlace( std::string& s ) {
7799
4
        std::transform( s.begin(), s.end(), s.begin(), ::tolower );
7800
1
    }
7801
    std::string toLower( std::string const& s ) {
7802
1
        std::string lc = s;
7803
1
        toLowerInPlace( lc );
7804
        return lc;
7805
    }
7806
    std::string trim( std::string const& str ) {
7807
        static char const* whitespaceChars = "\n\r\t ";
7808
        std::string::size_type start = str.find_first_not_of( whitespaceChars );
7809
        std::string::size_type end = str.find_last_not_of( whitespaceChars );
7810
7811
        return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
7812
    }
7813
7814
    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
7815
        bool replaced = false;
7816
        std::size_t i = str.find( replaceThis );
7817
        while( i != std::string::npos ) {
7818
            replaced = true;
7819
            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7820
            if( i < str.size()-withThis.size() )
7821
                i = str.find( replaceThis, i+withThis.size() );
7822
            else
7823
                i = std::string::npos;
7824
        }
7825
        return replaced;
7826
    }
7827
7828
2
    pluralise::pluralise( std::size_t count, std::string const& label )
7829
    :   m_count( count ),
7830
4
        m_label( label )
7831
    {}
7832
7833
2
    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
7834
8
        os << pluraliser.m_count << " " << pluraliser.m_label;
7835
2
        if( pluraliser.m_count != 1 )
7836
2
            os << "s";
7837
2
        return os;
7838
    }
7839
7840
4
    SourceLineInfo::SourceLineInfo() : line( 0 ){}
7841
1441788
    SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
7842
    :   file( _file ),
7843
4325364
        line( _line )
7844
1441788
    {}
7845
5756718
    SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
7846
    :   file( other.file ),
7847
11513436
        line( other.line )
7848
    {}
7849
    bool SourceLineInfo::empty() const {
7850
        return file.empty();
7851
    }
7852
    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
7853
        return line == other.line && file == other.file;
7854
    }
7855
    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
7856
        return line < other.line || ( line == other.line  && file < other.file );
7857
    }
7858
7859
757
    void seedRng( IConfig const& config ) {
7860
757
        if( config.rngSeed() != 0 )
7861
            std::srand( config.rngSeed() );
7862
757
    }
7863
    unsigned int rngSeed() {
7864
        return getCurrentContext().getConfig()->rngSeed();
7865
    }
7866
7867
8391
    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7868
#ifndef __GNUG__
7869
        os << info.file << "(" << info.line << ")";
7870
#else
7871
33564
        os << info.file << ":" << info.line;
7872
#endif
7873
8391
        return os;
7874
    }
7875
7876
    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
7877
        std::ostringstream oss;
7878
        oss << locationInfo << ": Internal Catch error: '" << message << "'";
7879
        if( alwaysTrue() )
7880
            throw std::logic_error( oss.str() );
7881
    }
7882
}
7883
7884
// #included from: catch_section.hpp
7885
#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
7886
7887
namespace Catch {
7888
7889
9147
    SectionInfo::SectionInfo
7890
        (   SourceLineInfo const& _lineInfo,
7891
            std::string const& _name,
7892
9147
            std::string const& _description )
7893
    :   name( _name ),
7894
        description( _description ),
7895
36588
        lineInfo( _lineInfo )
7896
9147
    {}
7897
7898
8391
    Section::Section( SectionInfo const& info )
7899
    :   m_info( info ),
7900

41955
        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
7901
    {
7902
16782
        m_timer.start();
7903
8391
    }
7904
7905
25173
    Section::~Section() {
7906
8391
        if( m_sectionIncluded ) {
7907
1233
            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
7908
411
            if( std::uncaught_exception() )
7909
                getResultCapture().sectionEndedEarly( endInfo );
7910
            else
7911
411
                getResultCapture().sectionEnded( endInfo );
7912
        }
7913
8391
    }
7914
7915
    // This indicates whether the section should be executed or not
7916
8391
    Section::operator bool() const {
7917
8391
        return m_sectionIncluded;
7918
    }
7919
7920
} // end namespace Catch
7921
7922
// #included from: catch_debugger.hpp
7923
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
7924
7925
#include <iostream>
7926
7927
#ifdef CATCH_PLATFORM_MAC
7928
7929
    #include <assert.h>
7930
    #include <stdbool.h>
7931
    #include <sys/types.h>
7932
    #include <unistd.h>
7933
    #include <sys/sysctl.h>
7934
7935
    namespace Catch{
7936
7937
        // The following function is taken directly from the following technical note:
7938
        // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7939
7940
        // Returns true if the current process is being debugged (either
7941
        // running under the debugger or has a debugger attached post facto).
7942
        bool isDebuggerActive(){
7943
7944
            int                 mib[4];
7945
            struct kinfo_proc   info;
7946
            size_t              size;
7947
7948
            // Initialize the flags so that, if sysctl fails for some bizarre
7949
            // reason, we get a predictable result.
7950
7951
            info.kp_proc.p_flag = 0;
7952
7953
            // Initialize mib, which tells sysctl the info we want, in this case
7954
            // we're looking for information about a specific process ID.
7955
7956
            mib[0] = CTL_KERN;
7957
            mib[1] = KERN_PROC;
7958
            mib[2] = KERN_PROC_PID;
7959
            mib[3] = getpid();
7960
7961
            // Call sysctl.
7962
7963
            size = sizeof(info);
7964
            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
7965
                Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7966
                return false;
7967
            }
7968
7969
            // We're being debugged if the P_TRACED flag is set.
7970
7971
            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7972
        }
7973
    } // namespace Catch
7974
7975
#elif defined(_MSC_VER)
7976
    extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7977
    namespace Catch {
7978
        bool isDebuggerActive() {
7979
            return IsDebuggerPresent() != 0;
7980
        }
7981
    }
7982
#elif defined(__MINGW32__)
7983
    extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7984
    namespace Catch {
7985
        bool isDebuggerActive() {
7986
            return IsDebuggerPresent() != 0;
7987
        }
7988
    }
7989
#else
7990
    namespace Catch {
7991
       inline bool isDebuggerActive() { return false; }
7992
    }
7993
#endif // Platform
7994
7995
#ifdef CATCH_PLATFORM_WINDOWS
7996
    extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
7997
    namespace Catch {
7998
        void writeToDebugConsole( std::string const& text ) {
7999
            ::OutputDebugStringA( text.c_str() );
8000
        }
8001
    }
8002
#else
8003
    namespace Catch {
8004
        void writeToDebugConsole( std::string const& text ) {
8005
            // !TBD: Need a version for Mac/ XCode and other IDEs
8006
            Catch::cout() << text;
8007
        }
8008
    }
8009
#endif // Platform
8010
8011
// #included from: catch_tostring.hpp
8012
#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
8013
8014
namespace Catch {
8015
8016
namespace Detail {
8017
8018
3
    const std::string unprintableString = "{?}";
8019
8020
    namespace {
8021
        const int hexThreshold = 255;
8022
8023
        struct Endianness {
8024
            enum Arch { Big, Little };
8025
8026
            static Arch which() {
8027
                union _{
8028
                    int asInt;
8029
                    char asChar[sizeof (int)];
8030
                } u;
8031
8032
                u.asInt = 1;
8033
                return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
8034
            }
8035
        };
8036
    }
8037
8038
10579
    std::string rawMemoryToString( const void *object, std::size_t size )
8039
    {
8040
        // Reverse order for little endian architectures
8041
10579
        int i = 0, end = static_cast<int>( size ), inc = 1;
8042
        if( Endianness::which() == Endianness::Little ) {
8043
10579
            i = end-1;
8044
10579
            end = inc = -1;
8045
        }
8046
8047
10579
        unsigned char const *bytes = static_cast<unsigned char const *>(object);
8048
21158
        std::ostringstream os;
8049
31737
        os << "0x" << std::setfill('0') << std::hex;
8050
179843
        for( ; i != end; i += inc )
8051
253896
             os << std::setw(2) << static_cast<unsigned>(bytes[i]);
8052
21158
       return os.str();
8053
    }
8054
}
8055
8056
164047
std::string toString( std::string const& value ) {
8057
328094
    std::string s = value;
8058

492141
    if( getCurrentContext().getConfig()->showInvisibles() ) {
8059
        for(size_t i = 0; i < s.size(); ++i ) {
8060
            std::string subs;
8061
            switch( s[i] ) {
8062
            case '\n': subs = "\\n"; break;
8063
            case '\t': subs = "\\t"; break;
8064
            default: break;
8065
            }
8066
            if( !subs.empty() ) {
8067
                s = s.substr( 0, i ) + subs + s.substr( i+1 );
8068
                ++i;
8069
            }
8070
        }
8071
    }
8072

492141
    return "\"" + s + "\"";
8073
}
8074
std::string toString( std::wstring const& value ) {
8075
8076
    std::string s;
8077
    s.reserve( value.size() );
8078
    for(size_t i = 0; i < value.size(); ++i )
8079
        s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
8080
    return Catch::toString( s );
8081
}
8082
8083
461
std::string toString( const char* const value ) {
8084



1383
    return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
8085
}
8086
8087
4
std::string toString( char* const value ) {
8088
4
    return Catch::toString( static_cast<const char*>( value ) );
8089
}
8090
8091
std::string toString( const wchar_t* const value )
8092
{
8093
	return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
8094
}
8095
8096
std::string toString( wchar_t* const value )
8097
{
8098
	return Catch::toString( static_cast<const wchar_t*>( value ) );
8099
}
8100
8101
34613
std::string toString( int value ) {
8102
69226
    std::ostringstream oss;
8103
34613
    oss << value;
8104
34613
    if( value > Detail::hexThreshold )
8105

8700
        oss << " (0x" << std::hex << value << ")";
8106
69226
    return oss.str();
8107
}
8108
8109
1557023
std::string toString( unsigned long value ) {
8110
3114046
    std::ostringstream oss;
8111
1557023
    oss << value;
8112
1557023
    if( value > Detail::hexThreshold )
8113
3725697
        oss << " (0x" << std::hex << value << ")";
8114
3114046
    return oss.str();
8115
}
8116
8117
7955
std::string toString( unsigned int value ) {
8118
1551230
    return Catch::toString( static_cast<unsigned long>( value ) );
8119
}
8120
8121
template<typename T>
8122
48
std::string fpToString( T value, int precision ) {
8123
96
    std::ostringstream oss;
8124
144
    oss << std::setprecision( precision )
8125
48
        << std::fixed
8126
        << value;
8127
48
    std::string d = oss.str();
8128
48
    std::size_t i = d.find_last_not_of( '0' );
8129



48
    if( i != std::string::npos && i != d.size()-1 ) {
8130

48
        if( d[i] == '.' )
8131
36
            i++;
8132

96
        d = d.substr( 0, i+1 );
8133
    }
8134
48
    return d;
8135
}
8136
8137
12
std::string toString( const double value ) {
8138
12
    return fpToString( value, 10 );
8139
}
8140
36
std::string toString( const float value ) {
8141
72
    return fpToString( value, 5 ) + "f";
8142
}
8143
8144
161707
std::string toString( bool value ) {
8145
485121
    return value ? "true" : "false";
8146
}
8147
8148
2469929
std::string toString( char value ) {
8149
2469929
    return value < ' '
8150
        ? toString( static_cast<unsigned int>( value ) )
8151
4939858
        : Detail::makeString( value );
8152
}
8153
8154
29
std::string toString( signed char value ) {
8155
29
    return toString( static_cast<char>( value ) );
8156
}
8157
8158
144
std::string toString( unsigned char value ) {
8159
144
    return toString( static_cast<char>( value ) );
8160
}
8161
8162
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
8163
std::string toString( long long value ) {
8164
    std::ostringstream oss;
8165
    oss << value;
8166
    if( value > Detail::hexThreshold )
8167
        oss << " (0x" << std::hex << value << ")";
8168
    return oss.str();
8169
}
8170
std::string toString( unsigned long long value ) {
8171
    std::ostringstream oss;
8172
    oss << value;
8173
    if( value > Detail::hexThreshold )
8174
        oss << " (0x" << std::hex << value << ")";
8175
    return oss.str();
8176
}
8177
#endif
8178
8179
#ifdef CATCH_CONFIG_CPP11_NULLPTR
8180
10395
std::string toString( std::nullptr_t ) {
8181
31185
    return "nullptr";
8182
}
8183
#endif
8184
8185
#ifdef __OBJC__
8186
    std::string toString( NSString const * const& nsstring ) {
8187
        if( !nsstring )
8188
            return "nil";
8189
        return "@" + toString([nsstring UTF8String]);
8190
    }
8191
    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
8192
        if( !nsstring )
8193
            return "nil";
8194
        return "@" + toString([nsstring UTF8String]);
8195
    }
8196
    std::string toString( NSObject* const& nsObject ) {
8197
        return toString( [nsObject description] );
8198
    }
8199
#endif
8200
8201
} // end namespace Catch
8202
8203
// #included from: catch_result_builder.hpp
8204
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
8205
8206
namespace Catch {
8207
8208
1433002
    std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
8209
1433033
        return secondArg.empty() || secondArg == "\"\""
8210
1433002
            ? capturedExpression
8211


1433002
            : capturedExpression + ", " + secondArg;
8212
    }
8213
1433002
    ResultBuilder::ResultBuilder(   char const* macroName,
8214
                                    SourceLineInfo const& lineInfo,
8215
                                    char const* capturedExpression,
8216
                                    ResultDisposition::Flags resultDisposition,
8217
1433002
                                    char const* secondArg )
8218

11464016
    :   m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
8219
        m_shouldDebugBreak( false ),
8220

11464016
        m_shouldThrow( false )
8221
1433002
    {}
8222
8223
    ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
8224
        m_data.resultType = result;
8225
        return *this;
8226
    }
8227
1432971
    ResultBuilder& ResultBuilder::setResultType( bool result ) {
8228
1432971
        m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
8229
1432971
        return *this;
8230
    }
8231
1432971
    ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
8232
2865942
        m_exprComponents.lhs = lhs;
8233
1432971
        return *this;
8234
    }
8235
1432502
    ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
8236
2865004
        m_exprComponents.rhs = rhs;
8237
1432502
        return *this;
8238
    }
8239
1432502
    ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
8240
2865004
        m_exprComponents.op = op;
8241
1432502
        return *this;
8242
    }
8243
8244
1432971
    void ResultBuilder::endExpression() {
8245
2865942
        m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
8246
1432971
        captureExpression();
8247
1432971
    }
8248
8249
    void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
8250
        m_assertionInfo.resultDisposition = resultDisposition;
8251
        m_stream.oss << Catch::translateActiveException();
8252
        captureResult( ResultWas::ThrewException );
8253
    }
8254
8255
    void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
8256
        setResultType( resultType );
8257
        captureExpression();
8258
    }
8259
31
    void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
8260
31
        if( expectedMessage.empty() )
8261
62
            captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
8262
        else
8263
            captureExpectedException( Matchers::Equals( expectedMessage ) );
8264
31
    }
8265
8266
31
    void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
8267
8268
31
        assert( m_exprComponents.testFalse == false );
8269
62
        AssertionResultData data = m_data;
8270
31
        data.resultType = ResultWas::Ok;
8271
62
        data.reconstructedExpression = m_assertionInfo.capturedExpression;
8272
8273
62
        std::string actualMessage = Catch::translateActiveException();
8274

31
        if( !matcher.match( actualMessage ) ) {
8275
            data.resultType = ResultWas::ExpressionFailed;
8276
            data.reconstructedExpression = actualMessage;
8277
        }
8278
62
        AssertionResult result( m_assertionInfo, data );
8279
31
        handleResult( result );
8280
31
    }
8281
8282
1432971
    void ResultBuilder::captureExpression() {
8283
2865942
        AssertionResult result = build();
8284
1432971
        handleResult( result );
8285
1432971
    }
8286
1433002
    void ResultBuilder::handleResult( AssertionResult const& result )
8287
    {
8288
1433002
        getResultCapture().assertionEnded( result );
8289
8290
1433002
        if( !result.isOk() ) {
8291
            if( getCurrentContext().getConfig()->shouldDebugBreak() )
8292
                m_shouldDebugBreak = true;
8293
            if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
8294
                m_shouldThrow = true;
8295
        }
8296
1433002
    }
8297
1433002
    void ResultBuilder::react() {
8298
1433002
        if( m_shouldThrow )
8299
            throw Catch::TestFailureException();
8300
1433002
    }
8301
8302
1433002
    bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
8303
124
    bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
8304
8305
1432971
    AssertionResult ResultBuilder::build() const
8306
    {
8307
1432971
        assert( m_data.resultType != ResultWas::Unknown );
8308
8309
2865942
        AssertionResultData data = m_data;
8310
8311
        // Flip bool results if testFalse is set
8312
1432971
        if( m_exprComponents.testFalse ) {
8313
15
            if( data.resultType == ResultWas::Ok )
8314
                data.resultType = ResultWas::ExpressionFailed;
8315
15
            else if( data.resultType == ResultWas::ExpressionFailed )
8316
15
                data.resultType = ResultWas::Ok;
8317
        }
8318
8319
4298913
        data.message = m_stream.oss.str();
8320
2865942
        data.reconstructedExpression = reconstructExpression();
8321
1432971
        if( m_exprComponents.testFalse ) {
8322
30
            if( m_exprComponents.op == "" )
8323
18
                data.reconstructedExpression = "!" + data.reconstructedExpression;
8324
            else
8325

18
                data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
8326
        }
8327
2865942
        return AssertionResult( m_assertionInfo, data );
8328
    }
8329
1432971
    std::string ResultBuilder::reconstructExpression() const {
8330
2865942
        if( m_exprComponents.op == "" )
8331
1407
            return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
8332
2865004
        else if( m_exprComponents.op == "matches" )
8333
            return m_exprComponents.lhs + " " + m_exprComponents.rhs;
8334
2865004
        else if( m_exprComponents.op != "!" ) {
8335

3677482
            if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
8336

3057458
                m_exprComponents.lhs.find("\n") == std::string::npos &&
8337
1624956
                m_exprComponents.rhs.find("\n") == std::string::npos )
8338

3249912
                return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
8339
            else
8340

2480096
                return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
8341
        }
8342
        else
8343
            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}";
8344
    }
8345
8346
} // end namespace Catch
8347
8348
// #included from: catch_tag_alias_registry.hpp
8349
#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8350
8351
// #included from: catch_tag_alias_registry.h
8352
#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
8353
8354
#include <map>
8355
8356
namespace Catch {
8357
8358
2
    class TagAliasRegistry : public ITagAliasRegistry {
8359
    public:
8360
        virtual ~TagAliasRegistry();
8361
        virtual Option<TagAlias> find( std::string const& alias ) const;
8362
        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
8363
        void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
8364
        static TagAliasRegistry& get();
8365
8366
    private:
8367
        std::map<std::string, TagAlias> m_registry;
8368
    };
8369
8370
} // end namespace Catch
8371
8372
#include <map>
8373
#include <iostream>
8374
8375
namespace Catch {
8376
8377
2
    TagAliasRegistry::~TagAliasRegistry() {}
8378
8379
    Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
8380
        std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
8381
        if( it != m_registry.end() )
8382
            return it->second;
8383
        else
8384
            return Option<TagAlias>();
8385
    }
8386
8387
1
    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
8388
1
        std::string expandedTestSpec = unexpandedTestSpec;
8389
3
        for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
8390
                it != itEnd;
8391
                ++it ) {
8392
            std::size_t pos = expandedTestSpec.find( it->first );
8393
            if( pos != std::string::npos ) {
8394
                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
8395
                                    it->second.tag +
8396
                                    expandedTestSpec.substr( pos + it->first.size() );
8397
            }
8398
        }
8399
1
        return expandedTestSpec;
8400
    }
8401
8402
    void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8403
8404
        if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
8405
            std::ostringstream oss;
8406
            oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
8407
            throw std::domain_error( oss.str().c_str() );
8408
        }
8409
        if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
8410
            std::ostringstream oss;
8411
            oss << "error: tag alias, \"" << alias << "\" already registered.\n"
8412
                << "\tFirst seen at " << find(alias)->lineInfo << "\n"
8413
                << "\tRedefined at " << lineInfo;
8414
            throw std::domain_error( oss.str().c_str() );
8415
        }
8416
    }
8417
8418
1
    TagAliasRegistry& TagAliasRegistry::get() {
8419

2
        static TagAliasRegistry instance;
8420
1
        return instance;
8421
8422
    }
8423
8424
    ITagAliasRegistry::~ITagAliasRegistry() {}
8425
1
    ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
8426
8427
    RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8428
        try {
8429
            TagAliasRegistry::get().add( alias, tag, lineInfo );
8430
        }
8431
        catch( std::exception& ex ) {
8432
            Colour colourGuard( Colour::Red );
8433
            Catch::cerr() << ex.what() << std::endl;
8434
            exit(1);
8435
        }
8436
    }
8437
8438
} // end namespace Catch
8439
8440
// #included from: ../reporters/catch_reporter_multi.hpp
8441
#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
8442
8443
namespace Catch {
8444
8445
class MultipleReporters : public SharedImpl<IStreamingReporter> {
8446
    typedef std::vector<Ptr<IStreamingReporter> > Reporters;
8447
    Reporters m_reporters;
8448
8449
public:
8450
    void add( Ptr<IStreamingReporter> const& reporter ) {
8451
        m_reporters.push_back( reporter );
8452
    }
8453
8454
public: // IStreamingReporter
8455
8456
    virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8457
        return m_reporters[0]->getPreferences();
8458
    }
8459
8460
    virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
8461
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8462
                it != itEnd;
8463
                ++it )
8464
            (*it)->noMatchingTestCases( spec );
8465
    }
8466
8467
    virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
8468
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8469
                it != itEnd;
8470
                ++it )
8471
            (*it)->testRunStarting( testRunInfo );
8472
    }
8473
8474
    virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
8475
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8476
                it != itEnd;
8477
                ++it )
8478
            (*it)->testGroupStarting( groupInfo );
8479
    }
8480
8481
    virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8482
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8483
                it != itEnd;
8484
                ++it )
8485
            (*it)->testCaseStarting( testInfo );
8486
    }
8487
8488
    virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8489
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8490
                it != itEnd;
8491
                ++it )
8492
            (*it)->sectionStarting( sectionInfo );
8493
    }
8494
8495
    virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
8496
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8497
                it != itEnd;
8498
                ++it )
8499
            (*it)->assertionStarting( assertionInfo );
8500
    }
8501
8502
    // The return value indicates if the messages buffer should be cleared:
8503
    virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8504
        bool clearBuffer = false;
8505
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8506
                it != itEnd;
8507
                ++it )
8508
            clearBuffer |= (*it)->assertionEnded( assertionStats );
8509
        return clearBuffer;
8510
    }
8511
8512
    virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8513
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8514
                it != itEnd;
8515
                ++it )
8516
            (*it)->sectionEnded( sectionStats );
8517
    }
8518
8519
    virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8520
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8521
                it != itEnd;
8522
                ++it )
8523
            (*it)->testCaseEnded( testCaseStats );
8524
    }
8525
8526
    virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8527
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8528
                it != itEnd;
8529
                ++it )
8530
            (*it)->testGroupEnded( testGroupStats );
8531
    }
8532
8533
    virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8534
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8535
                it != itEnd;
8536
                ++it )
8537
            (*it)->testRunEnded( testRunStats );
8538
    }
8539
8540
    virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8541
        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8542
                it != itEnd;
8543
                ++it )
8544
            (*it)->skipTest( testInfo );
8545
    }
8546
8547
    virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
8548
        return this;
8549
    }
8550
8551
};
8552
8553
1
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
8554
1
    Ptr<IStreamingReporter> resultingReporter;
8555
8556
1
    if( existingReporter ) {
8557
        MultipleReporters* multi = existingReporter->tryAsMulti();
8558
        if( !multi ) {
8559
            multi = new MultipleReporters;
8560
            resultingReporter = Ptr<IStreamingReporter>( multi );
8561
            if( existingReporter )
8562
                multi->add( existingReporter );
8563
        }
8564
        else
8565
            resultingReporter = existingReporter;
8566
        multi->add( additionalReporter );
8567
    }
8568
    else
8569
1
        resultingReporter = additionalReporter;
8570
8571
1
    return resultingReporter;
8572
}
8573
8574
} // end namespace Catch
8575
8576
// #included from: ../reporters/catch_reporter_xml.hpp
8577
#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
8578
8579
// #included from: catch_reporter_bases.hpp
8580
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
8581
8582
#include <cstring>
8583
8584
namespace Catch {
8585
8586
    struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
8587
8588
        StreamingReporterBase( ReporterConfig const& _config )
8589
1
        :   m_config( _config.fullConfig() ),
8590
8
            stream( _config.stream() )
8591
        {
8592
            m_reporterPrefs.shouldRedirectStdOut = false;
8593
        }
8594
8595
756
        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8596
756
            return m_reporterPrefs;
8597
        }
8598
8599
        virtual ~StreamingReporterBase() CATCH_OVERRIDE;
8600
8601
        virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
8602
8603
1
        virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
8604
2
            currentTestRunInfo = _testRunInfo;
8605
1
        }
8606
1
        virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
8607
2
            currentGroupInfo = _groupInfo;
8608
1
        }
8609
8610
395
        virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
8611
790
            currentTestCaseInfo = _testInfo;
8612
395
        }
8613
        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
8614
1167
            m_sectionStack.push_back( _sectionInfo );
8615
        }
8616
8617
        virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
8618
1167
            m_sectionStack.pop_back();
8619
        }
8620
        virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
8621
790
            currentTestCaseInfo.reset();
8622
        }
8623
        virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
8624
2
            currentGroupInfo.reset();
8625
        }
8626
1
        virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
8627
2
            currentTestCaseInfo.reset();
8628
2
            currentGroupInfo.reset();
8629
2
            currentTestRunInfo.reset();
8630
1
        }
8631
8632
        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
8633
            // Don't do anything with this by default.
8634
            // It can optionally be overridden in the derived class.
8635
        }
8636
8637
        Ptr<IConfig const> m_config;
8638
        std::ostream& stream;
8639
8640
        LazyStat<TestRunInfo> currentTestRunInfo;
8641
        LazyStat<GroupInfo> currentGroupInfo;
8642
        LazyStat<TestCaseInfo> currentTestCaseInfo;
8643
8644
        std::vector<SectionInfo> m_sectionStack;
8645
        ReporterPreferences m_reporterPrefs;
8646
    };
8647
8648
    struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
8649
        template<typename T, typename ChildNodeT>
8650
        struct Node : SharedImpl<> {
8651
            explicit Node( T const& _value ) : value( _value ) {}
8652
            virtual ~Node() {}
8653
8654
            typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
8655
            T value;
8656
            ChildNodes children;
8657
        };
8658
        struct SectionNode : SharedImpl<> {
8659
            explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
8660
            virtual ~SectionNode();
8661
8662
            bool operator == ( SectionNode const& other ) const {
8663
                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
8664
            }
8665
            bool operator == ( Ptr<SectionNode> const& other ) const {
8666
                return operator==( *other );
8667
            }
8668
8669
            SectionStats stats;
8670
            typedef std::vector<Ptr<SectionNode> > ChildSections;
8671
            typedef std::vector<AssertionStats> Assertions;
8672
            ChildSections childSections;
8673
            Assertions assertions;
8674
            std::string stdOut;
8675
            std::string stdErr;
8676
        };
8677
8678
        struct BySectionInfo {
8679
            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
8680
			BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
8681
            bool operator() ( Ptr<SectionNode> const& node ) const {
8682
                return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
8683
            }
8684
        private:
8685
			void operator=( BySectionInfo const& );
8686
            SectionInfo const& m_other;
8687
        };
8688
8689
        typedef Node<TestCaseStats, SectionNode> TestCaseNode;
8690
        typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
8691
        typedef Node<TestRunStats, TestGroupNode> TestRunNode;
8692
8693
        CumulativeReporterBase( ReporterConfig const& _config )
8694
        :   m_config( _config.fullConfig() ),
8695
            stream( _config.stream() )
8696
        {
8697
            m_reporterPrefs.shouldRedirectStdOut = false;
8698
        }
8699
        ~CumulativeReporterBase();
8700
8701
        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8702
            return m_reporterPrefs;
8703
        }
8704
8705
        virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
8706
        virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
8707
8708
        virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
8709
8710
        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8711
            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
8712
            Ptr<SectionNode> node;
8713
            if( m_sectionStack.empty() ) {
8714
                if( !m_rootSection )
8715
                    m_rootSection = new SectionNode( incompleteStats );
8716
                node = m_rootSection;
8717
            }
8718
            else {
8719
                SectionNode& parentNode = *m_sectionStack.back();
8720
                SectionNode::ChildSections::const_iterator it =
8721
                    std::find_if(   parentNode.childSections.begin(),
8722
                                    parentNode.childSections.end(),
8723
                                    BySectionInfo( sectionInfo ) );
8724
                if( it == parentNode.childSections.end() ) {
8725
                    node = new SectionNode( incompleteStats );
8726
                    parentNode.childSections.push_back( node );
8727
                }
8728
                else
8729
                    node = *it;
8730
            }
8731
            m_sectionStack.push_back( node );
8732
            m_deepestSection = node;
8733
        }
8734
8735
        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
8736
8737
        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8738
            assert( !m_sectionStack.empty() );
8739
            SectionNode& sectionNode = *m_sectionStack.back();
8740
            sectionNode.assertions.push_back( assertionStats );
8741
            return true;
8742
        }
8743
        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8744
            assert( !m_sectionStack.empty() );
8745
            SectionNode& node = *m_sectionStack.back();
8746
            node.stats = sectionStats;
8747
            m_sectionStack.pop_back();
8748
        }
8749
        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8750
            Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
8751
            assert( m_sectionStack.size() == 0 );
8752
            node->children.push_back( m_rootSection );
8753
            m_testCases.push_back( node );
8754
            m_rootSection.reset();
8755
8756
            assert( m_deepestSection );
8757
            m_deepestSection->stdOut = testCaseStats.stdOut;
8758
            m_deepestSection->stdErr = testCaseStats.stdErr;
8759
        }
8760
        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8761
            Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
8762
            node->children.swap( m_testCases );
8763
            m_testGroups.push_back( node );
8764
        }
8765
        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8766
            Ptr<TestRunNode> node = new TestRunNode( testRunStats );
8767
            node->children.swap( m_testGroups );
8768
            m_testRuns.push_back( node );
8769
            testRunEndedCumulative();
8770
        }
8771
        virtual void testRunEndedCumulative() = 0;
8772
8773
        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
8774
8775
        Ptr<IConfig const> m_config;
8776
        std::ostream& stream;
8777
        std::vector<AssertionStats> m_assertions;
8778
        std::vector<std::vector<Ptr<SectionNode> > > m_sections;
8779
        std::vector<Ptr<TestCaseNode> > m_testCases;
8780
        std::vector<Ptr<TestGroupNode> > m_testGroups;
8781
8782
        std::vector<Ptr<TestRunNode> > m_testRuns;
8783
8784
        Ptr<SectionNode> m_rootSection;
8785
        Ptr<SectionNode> m_deepestSection;
8786
        std::vector<Ptr<SectionNode> > m_sectionStack;
8787
        ReporterPreferences m_reporterPrefs;
8788
8789
    };
8790
8791
    template<char C>
8792
    char const* getLineOfChars() {
8793
        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
8794
        if( !*line ) {
8795
            memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
8796
            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
8797
        }
8798
        return line;
8799
    }
8800
8801
    struct TestEventListenerBase : StreamingReporterBase {
8802
        TestEventListenerBase( ReporterConfig const& _config )
8803
        :   StreamingReporterBase( _config )
8804
        {}
8805
8806
        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
8807
        virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
8808
            return false;
8809
        }
8810
    };
8811
8812
} // end namespace Catch
8813
8814
// #included from: ../internal/catch_reporter_registrars.hpp
8815
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
8816
8817
namespace Catch {
8818
8819
    template<typename T>
8820
    class LegacyReporterRegistrar {
8821
8822
        class ReporterFactory : public IReporterFactory {
8823
            virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8824
                return new LegacyReporterAdapter( new T( config ) );
8825
            }
8826
8827
            virtual std::string getDescription() const {
8828
                return T::getDescription();
8829
            }
8830
        };
8831
8832
    public:
8833
8834
        LegacyReporterRegistrar( std::string const& name ) {
8835
            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8836
        }
8837
    };
8838
8839
    template<typename T>
8840
    class ReporterRegistrar {
8841
8842
16
        class ReporterFactory : public SharedImpl<IReporterFactory> {
8843
8844
            // *** Please Note ***:
8845
            // - If you end up here looking at a compiler error because it's trying to register
8846
            // your custom reporter class be aware that the native reporter interface has changed
8847
            // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
8848
            // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
8849
            // However please consider updating to the new interface as the old one is now
8850
            // deprecated and will probably be removed quite soon!
8851
            // Please contact me via github if you have any questions at all about this.
8852
            // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
8853
            // no idea who is actually using custom reporters at all (possibly no-one!).
8854
            // The new interface is designed to minimise exposure to interface changes in the future.
8855
1
            virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8856

2
                return new T( config );
8857
            }
8858
8859
            virtual std::string getDescription() const {
8860
                return T::getDescription();
8861
            }
8862
        };
8863
8864
    public:
8865
8866
4
        ReporterRegistrar( std::string const& name ) {
8867


12
            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8868
4
        }
8869
    };
8870
8871
    template<typename T>
8872
    class ListenerRegistrar {
8873
8874
        class ListenerFactory : public SharedImpl<IReporterFactory> {
8875
8876
            virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8877
                return new T( config );
8878
            }
8879
            virtual std::string getDescription() const {
8880
                return "";
8881
            }
8882
        };
8883
8884
    public:
8885
8886
        ListenerRegistrar() {
8887
            getMutableRegistryHub().registerListener( new ListenerFactory() );
8888
        }
8889
    };
8890
}
8891
8892
#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
8893
    namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
8894
8895
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
8896
    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
8897
8898
#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
8899
    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
8900
8901
// #included from: ../internal/catch_xmlwriter.hpp
8902
#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
8903
8904
#include <sstream>
8905
#include <string>
8906
#include <vector>
8907
#include <iomanip>
8908
8909
namespace Catch {
8910
8911
    class XmlEncode {
8912
    public:
8913
        enum ForWhat { ForTextNodes, ForAttributes };
8914
8915
        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
8916
        :   m_str( str ),
8917
            m_forWhat( forWhat )
8918
        {}
8919
8920
        void encodeTo( std::ostream& os ) const {
8921
8922
            // Apostrophe escaping not necessary if we always use " to write attributes
8923
            // (see: http://www.w3.org/TR/xml/#syntax)
8924
8925
            for( std::size_t i = 0; i < m_str.size(); ++ i ) {
8926
                char c = m_str[i];
8927
                switch( c ) {
8928
                    case '<':   os << "&lt;"; break;
8929
                    case '&':   os << "&amp;"; break;
8930
8931
                    case '>':
8932
                        // See: http://www.w3.org/TR/xml/#syntax
8933
                        if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
8934
                            os << "&gt;";
8935
                        else
8936
                            os << c;
8937
                        break;
8938
8939
                    case '\"':
8940
                        if( m_forWhat == ForAttributes )
8941
                            os << "&quot;";
8942
                        else
8943
                            os << c;
8944
                        break;
8945
8946
                    default:
8947
                        // Escape control chars - based on contribution by @espenalb in PR #465
8948
                        if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
8949
                            os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
8950
                        else
8951
                            os << c;
8952
                }
8953
            }
8954
        }
8955
8956
        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
8957
            xmlEncode.encodeTo( os );
8958
            return os;
8959
        }
8960
8961
    private:
8962
        std::string m_str;
8963
        ForWhat m_forWhat;
8964
    };
8965
8966
    class XmlWriter {
8967
    public:
8968
8969
        class ScopedElement {
8970
        public:
8971
            ScopedElement( XmlWriter* writer )
8972
            :   m_writer( writer )
8973
            {}
8974
8975
            ScopedElement( ScopedElement const& other )
8976
            :   m_writer( other.m_writer ){
8977
                other.m_writer = CATCH_NULL;
8978
            }
8979
8980
            ~ScopedElement() {
8981
                if( m_writer )
8982
                    m_writer->endElement();
8983
            }
8984
8985
            ScopedElement& writeText( std::string const& text, bool indent = true ) {
8986
                m_writer->writeText( text, indent );
8987
                return *this;
8988
            }
8989
8990
            template<typename T>
8991
            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
8992
                m_writer->writeAttribute( name, attribute );
8993
                return *this;
8994
            }
8995
8996
        private:
8997
            mutable XmlWriter* m_writer;
8998
        };
8999
9000
        XmlWriter()
9001
        :   m_tagIsOpen( false ),
9002
            m_needsNewline( false ),
9003
            m_os( &Catch::cout() )
9004
        {}
9005
9006
        XmlWriter( std::ostream& os )
9007
        :   m_tagIsOpen( false ),
9008
            m_needsNewline( false ),
9009
            m_os( &os )
9010
        {}
9011
9012
        ~XmlWriter() {
9013
            while( !m_tags.empty() )
9014
                endElement();
9015
        }
9016
9017
        XmlWriter& startElement( std::string const& name ) {
9018
            ensureTagClosed();
9019
            newlineIfNecessary();
9020
            stream() << m_indent << "<" << name;
9021
            m_tags.push_back( name );
9022
            m_indent += "  ";
9023
            m_tagIsOpen = true;
9024
            return *this;
9025
        }
9026
9027
        ScopedElement scopedElement( std::string const& name ) {
9028
            ScopedElement scoped( this );
9029
            startElement( name );
9030
            return scoped;
9031
        }
9032
9033
        XmlWriter& endElement() {
9034
            newlineIfNecessary();
9035
            m_indent = m_indent.substr( 0, m_indent.size()-2 );
9036
            if( m_tagIsOpen ) {
9037
                stream() << "/>\n";
9038
                m_tagIsOpen = false;
9039
            }
9040
            else {
9041
                stream() << m_indent << "</" << m_tags.back() << ">\n";
9042
            }
9043
            m_tags.pop_back();
9044
            return *this;
9045
        }
9046
9047
        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
9048
            if( !name.empty() && !attribute.empty() )
9049
                stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
9050
            return *this;
9051
        }
9052
9053
        XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
9054
            stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
9055
            return *this;
9056
        }
9057
9058
        template<typename T>
9059
        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
9060
            std::ostringstream oss;
9061
            oss << attribute;
9062
            return writeAttribute( name, oss.str() );
9063
        }
9064
9065
        XmlWriter& writeText( std::string const& text, bool indent = true ) {
9066
            if( !text.empty() ){
9067
                bool tagWasOpen = m_tagIsOpen;
9068
                ensureTagClosed();
9069
                if( tagWasOpen && indent )
9070
                    stream() << m_indent;
9071
                stream() << XmlEncode( text );
9072
                m_needsNewline = true;
9073
            }
9074
            return *this;
9075
        }
9076
9077
        XmlWriter& writeComment( std::string const& text ) {
9078
            ensureTagClosed();
9079
            stream() << m_indent << "<!--" << text << "-->";
9080
            m_needsNewline = true;
9081
            return *this;
9082
        }
9083
9084
        XmlWriter& writeBlankLine() {
9085
            ensureTagClosed();
9086
            stream() << "\n";
9087
            return *this;
9088
        }
9089
9090
        void setStream( std::ostream& os ) {
9091
            m_os = &os;
9092
        }
9093
9094
    private:
9095
        XmlWriter( XmlWriter const& );
9096
        void operator=( XmlWriter const& );
9097
9098
        std::ostream& stream() {
9099
            return *m_os;
9100
        }
9101
9102
        void ensureTagClosed() {
9103
            if( m_tagIsOpen ) {
9104
                stream() << ">\n";
9105
                m_tagIsOpen = false;
9106
            }
9107
        }
9108
9109
        void newlineIfNecessary() {
9110
            if( m_needsNewline ) {
9111
                stream() << "\n";
9112
                m_needsNewline = false;
9113
            }
9114
        }
9115
9116
        bool m_tagIsOpen;
9117
        bool m_needsNewline;
9118
        std::vector<std::string> m_tags;
9119
        std::string m_indent;
9120
        std::ostream* m_os;
9121
    };
9122
9123
}
9124
// #included from: catch_reenable_warnings.h
9125
9126
#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
9127
9128
#ifdef __clang__
9129
#    ifdef __ICC // icpc defines the __clang__ macro
9130
#        pragma warning(pop)
9131
#    else
9132
#        pragma clang diagnostic pop
9133
#    endif
9134
#elif defined __GNUC__
9135
#    pragma GCC diagnostic pop
9136
#endif
9137
9138
9139
namespace Catch {
9140
    class XmlReporter : public StreamingReporterBase {
9141
    public:
9142
        XmlReporter( ReporterConfig const& _config )
9143
        :   StreamingReporterBase( _config ),
9144
            m_sectionDepth( 0 )
9145
        {
9146
            m_reporterPrefs.shouldRedirectStdOut = true;
9147
        }
9148
9149
        virtual ~XmlReporter() CATCH_OVERRIDE;
9150
9151
        static std::string getDescription() {
9152
            return "Reports test results as an XML document";
9153
        }
9154
9155
    public: // StreamingReporterBase
9156
9157
        virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
9158
            StreamingReporterBase::noMatchingTestCases( s );
9159
        }
9160
9161
        virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
9162
            StreamingReporterBase::testRunStarting( testInfo );
9163
            m_xml.setStream( stream );
9164
            m_xml.startElement( "Catch" );
9165
            if( !m_config->name().empty() )
9166
                m_xml.writeAttribute( "name", m_config->name() );
9167
        }
9168
9169
        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9170
            StreamingReporterBase::testGroupStarting( groupInfo );
9171
            m_xml.startElement( "Group" )
9172
                .writeAttribute( "name", groupInfo.name );
9173
        }
9174
9175
        virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
9176
            StreamingReporterBase::testCaseStarting(testInfo);
9177
            m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
9178
9179
            if ( m_config->showDurations() == ShowDurations::Always )
9180
                m_testCaseTimer.start();
9181
        }
9182
9183
        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
9184
            StreamingReporterBase::sectionStarting( sectionInfo );
9185
            if( m_sectionDepth++ > 0 ) {
9186
                m_xml.startElement( "Section" )
9187
                    .writeAttribute( "name", trim( sectionInfo.name ) )
9188
                    .writeAttribute( "description", sectionInfo.description );
9189
            }
9190
        }
9191
9192
        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
9193
9194
        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9195
            const AssertionResult& assertionResult = assertionStats.assertionResult;
9196
9197
            // Print any info messages in <Info> tags.
9198
            if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
9199
                for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
9200
                        it != itEnd;
9201
                        ++it ) {
9202
                    if( it->type == ResultWas::Info ) {
9203
                        m_xml.scopedElement( "Info" )
9204
                            .writeText( it->message );
9205
                    } else if ( it->type == ResultWas::Warning ) {
9206
                        m_xml.scopedElement( "Warning" )
9207
                            .writeText( it->message );
9208
                    }
9209
                }
9210
            }
9211
9212
            // Drop out if result was successful but we're not printing them.
9213
            if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
9214
                return true;
9215
9216
            // Print the expression if there is one.
9217
            if( assertionResult.hasExpression() ) {
9218
                m_xml.startElement( "Expression" )
9219
                    .writeAttribute( "success", assertionResult.succeeded() )
9220
					.writeAttribute( "type", assertionResult.getTestMacroName() )
9221
                    .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9222
                    .writeAttribute( "line", assertionResult.getSourceInfo().line );
9223
9224
                m_xml.scopedElement( "Original" )
9225
                    .writeText( assertionResult.getExpression() );
9226
                m_xml.scopedElement( "Expanded" )
9227
                    .writeText( assertionResult.getExpandedExpression() );
9228
            }
9229
9230
            // And... Print a result applicable to each result type.
9231
            switch( assertionResult.getResultType() ) {
9232
                case ResultWas::ThrewException:
9233
                    m_xml.scopedElement( "Exception" )
9234
                        .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9235
                        .writeAttribute( "line", assertionResult.getSourceInfo().line )
9236
                        .writeText( assertionResult.getMessage() );
9237
                    break;
9238
                case ResultWas::FatalErrorCondition:
9239
                    m_xml.scopedElement( "Fatal Error Condition" )
9240
                        .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9241
                        .writeAttribute( "line", assertionResult.getSourceInfo().line )
9242
                        .writeText( assertionResult.getMessage() );
9243
                    break;
9244
                case ResultWas::Info:
9245
                    m_xml.scopedElement( "Info" )
9246
                        .writeText( assertionResult.getMessage() );
9247
                    break;
9248
                case ResultWas::Warning:
9249
                    // Warning will already have been written
9250
                    break;
9251
                case ResultWas::ExplicitFailure:
9252
                    m_xml.scopedElement( "Failure" )
9253
                        .writeText( assertionResult.getMessage() );
9254
                    break;
9255
                default:
9256
                    break;
9257
            }
9258
9259
            if( assertionResult.hasExpression() )
9260
                m_xml.endElement();
9261
9262
            return true;
9263
        }
9264
9265
        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
9266
            StreamingReporterBase::sectionEnded( sectionStats );
9267
            if( --m_sectionDepth > 0 ) {
9268
                XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
9269
                e.writeAttribute( "successes", sectionStats.assertions.passed );
9270
                e.writeAttribute( "failures", sectionStats.assertions.failed );
9271
                e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
9272
9273
                if ( m_config->showDurations() == ShowDurations::Always )
9274
                    e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
9275
9276
                m_xml.endElement();
9277
            }
9278
        }
9279
9280
        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9281
            StreamingReporterBase::testCaseEnded( testCaseStats );
9282
            XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
9283
            e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
9284
9285
            if ( m_config->showDurations() == ShowDurations::Always )
9286
                e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
9287
9288
            m_xml.endElement();
9289
        }
9290
9291
        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9292
            StreamingReporterBase::testGroupEnded( testGroupStats );
9293
            // TODO: Check testGroupStats.aborting and act accordingly.
9294
            m_xml.scopedElement( "OverallResults" )
9295
                .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
9296
                .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
9297
                .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
9298
            m_xml.endElement();
9299
        }
9300
9301
        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
9302
            StreamingReporterBase::testRunEnded( testRunStats );
9303
            m_xml.scopedElement( "OverallResults" )
9304
                .writeAttribute( "successes", testRunStats.totals.assertions.passed )
9305
                .writeAttribute( "failures", testRunStats.totals.assertions.failed )
9306
                .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
9307
            m_xml.endElement();
9308
        }
9309
9310
    private:
9311
        Timer m_testCaseTimer;
9312
        XmlWriter m_xml;
9313
        int m_sectionDepth;
9314
    };
9315
9316
4
     INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
9317
9318
} // end namespace Catch
9319
9320
// #included from: ../reporters/catch_reporter_junit.hpp
9321
#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
9322
9323
#include <assert.h>
9324
9325
namespace Catch {
9326
9327
    class JunitReporter : public CumulativeReporterBase {
9328
    public:
9329
        JunitReporter( ReporterConfig const& _config )
9330
        :   CumulativeReporterBase( _config ),
9331
            xml( _config.stream() )
9332
        {
9333
            m_reporterPrefs.shouldRedirectStdOut = true;
9334
        }
9335
9336
        virtual ~JunitReporter() CATCH_OVERRIDE;
9337
9338
        static std::string getDescription() {
9339
            return "Reports test results in an XML format that looks like Ant's junitreport target";
9340
        }
9341
9342
        virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
9343
9344
        virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
9345
            CumulativeReporterBase::testRunStarting( runInfo );
9346
            xml.startElement( "testsuites" );
9347
        }
9348
9349
        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9350
            suiteTimer.start();
9351
            stdOutForSuite.str("");
9352
            stdErrForSuite.str("");
9353
            unexpectedExceptions = 0;
9354
            CumulativeReporterBase::testGroupStarting( groupInfo );
9355
        }
9356
9357
        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9358
            if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
9359
                unexpectedExceptions++;
9360
            return CumulativeReporterBase::assertionEnded( assertionStats );
9361
        }
9362
9363
        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9364
            stdOutForSuite << testCaseStats.stdOut;
9365
            stdErrForSuite << testCaseStats.stdErr;
9366
            CumulativeReporterBase::testCaseEnded( testCaseStats );
9367
        }
9368
9369
        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9370
            double suiteTime = suiteTimer.getElapsedSeconds();
9371
            CumulativeReporterBase::testGroupEnded( testGroupStats );
9372
            writeGroup( *m_testGroups.back(), suiteTime );
9373
        }
9374
9375
        virtual void testRunEndedCumulative() CATCH_OVERRIDE {
9376
            xml.endElement();
9377
        }
9378
9379
        void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
9380
            XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
9381
            TestGroupStats const& stats = groupNode.value;
9382
            xml.writeAttribute( "name", stats.groupInfo.name );
9383
            xml.writeAttribute( "errors", unexpectedExceptions );
9384
            xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
9385
            xml.writeAttribute( "tests", stats.totals.assertions.total() );
9386
            xml.writeAttribute( "hostname", "tbd" ); // !TBD
9387
            if( m_config->showDurations() == ShowDurations::Never )
9388
                xml.writeAttribute( "time", "" );
9389
            else
9390
                xml.writeAttribute( "time", suiteTime );
9391
            xml.writeAttribute( "timestamp", "tbd" ); // !TBD
9392
9393
            // Write test cases
9394
            for( TestGroupNode::ChildNodes::const_iterator
9395
                    it = groupNode.children.begin(), itEnd = groupNode.children.end();
9396
                    it != itEnd;
9397
                    ++it )
9398
                writeTestCase( **it );
9399
9400
            xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
9401
            xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
9402
        }
9403
9404
        void writeTestCase( TestCaseNode const& testCaseNode ) {
9405
            TestCaseStats const& stats = testCaseNode.value;
9406
9407
            // All test cases have exactly one section - which represents the
9408
            // test case itself. That section may have 0-n nested sections
9409
            assert( testCaseNode.children.size() == 1 );
9410
            SectionNode const& rootSection = *testCaseNode.children.front();
9411
9412
            std::string className = stats.testInfo.className;
9413
9414
            if( className.empty() ) {
9415
                if( rootSection.childSections.empty() )
9416
                    className = "global";
9417
            }
9418
            writeSection( className, "", rootSection );
9419
        }
9420
9421
        void writeSection(  std::string const& className,
9422
                            std::string const& rootName,
9423
                            SectionNode const& sectionNode ) {
9424
            std::string name = trim( sectionNode.stats.sectionInfo.name );
9425
            if( !rootName.empty() )
9426
                name = rootName + "/" + name;
9427
9428
            if( !sectionNode.assertions.empty() ||
9429
                !sectionNode.stdOut.empty() ||
9430
                !sectionNode.stdErr.empty() ) {
9431
                XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
9432
                if( className.empty() ) {
9433
                    xml.writeAttribute( "classname", name );
9434
                    xml.writeAttribute( "name", "root" );
9435
                }
9436
                else {
9437
                    xml.writeAttribute( "classname", className );
9438
                    xml.writeAttribute( "name", name );
9439
                }
9440
                xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
9441
9442
                writeAssertions( sectionNode );
9443
9444
                if( !sectionNode.stdOut.empty() )
9445
                    xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
9446
                if( !sectionNode.stdErr.empty() )
9447
                    xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
9448
            }
9449
            for( SectionNode::ChildSections::const_iterator
9450
                    it = sectionNode.childSections.begin(),
9451
                    itEnd = sectionNode.childSections.end();
9452
                    it != itEnd;
9453
                    ++it )
9454
                if( className.empty() )
9455
                    writeSection( name, "", **it );
9456
                else
9457
                    writeSection( className, name, **it );
9458
        }
9459
9460
        void writeAssertions( SectionNode const& sectionNode ) {
9461
            for( SectionNode::Assertions::const_iterator
9462
                    it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
9463
                    it != itEnd;
9464
                    ++it )
9465
                writeAssertion( *it );
9466
        }
9467
        void writeAssertion( AssertionStats const& stats ) {
9468
            AssertionResult const& result = stats.assertionResult;
9469
            if( !result.isOk() ) {
9470
                std::string elementName;
9471
                switch( result.getResultType() ) {
9472
                    case ResultWas::ThrewException:
9473
                    case ResultWas::FatalErrorCondition:
9474
                        elementName = "error";
9475
                        break;
9476
                    case ResultWas::ExplicitFailure:
9477
                        elementName = "failure";
9478
                        break;
9479
                    case ResultWas::ExpressionFailed:
9480
                        elementName = "failure";
9481
                        break;
9482
                    case ResultWas::DidntThrowException:
9483
                        elementName = "failure";
9484
                        break;
9485
9486
                    // We should never see these here:
9487
                    case ResultWas::Info:
9488
                    case ResultWas::Warning:
9489
                    case ResultWas::Ok:
9490
                    case ResultWas::Unknown:
9491
                    case ResultWas::FailureBit:
9492
                    case ResultWas::Exception:
9493
                        elementName = "internalError";
9494
                        break;
9495
                }
9496
9497
                XmlWriter::ScopedElement e = xml.scopedElement( elementName );
9498
9499
                xml.writeAttribute( "message", result.getExpandedExpression() );
9500
                xml.writeAttribute( "type", result.getTestMacroName() );
9501
9502
                std::ostringstream oss;
9503
                if( !result.getMessage().empty() )
9504
                    oss << result.getMessage() << "\n";
9505
                for( std::vector<MessageInfo>::const_iterator
9506
                        it = stats.infoMessages.begin(),
9507
                        itEnd = stats.infoMessages.end();
9508
                            it != itEnd;
9509
                            ++it )
9510
                    if( it->type == ResultWas::Info )
9511
                        oss << it->message << "\n";
9512
9513
                oss << "at " << result.getSourceInfo();
9514
                xml.writeText( oss.str(), false );
9515
            }
9516
        }
9517
9518
        XmlWriter xml;
9519
        Timer suiteTimer;
9520
        std::ostringstream stdOutForSuite;
9521
        std::ostringstream stdErrForSuite;
9522
        unsigned int unexpectedExceptions;
9523
    };
9524
9525
4
    INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
9526
9527
} // end namespace Catch
9528
9529
// #included from: ../reporters/catch_reporter_console.hpp
9530
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
9531
9532
namespace Catch {
9533
9534
    struct ConsoleReporter : StreamingReporterBase {
9535
        ConsoleReporter( ReporterConfig const& _config )
9536
1
        :   StreamingReporterBase( _config ),
9537
2
            m_headerPrinted( false )
9538
        {}
9539
9540
        virtual ~ConsoleReporter() CATCH_OVERRIDE;
9541
        static std::string getDescription() {
9542
            return "Reports test results as plain lines of text";
9543
        }
9544
9545
        virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
9546
            stream << "No test cases matched '" << spec << "'" << std::endl;
9547
        }
9548
9549
        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
9550
        }
9551
9552
1433002
        virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
9553
1433002
            AssertionResult const& result = _assertionStats.assertionResult;
9554
9555
1433002
            bool printInfoMessages = true;
9556
9557
            // Drop out if result was successful and we're not printing those
9558

4299006
            if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9559
1433002
                if( result.getResultType() != ResultWas::Warning )
9560
                    return false;
9561
                printInfoMessages = false;
9562
            }
9563
9564
            lazyPrint();
9565
9566
            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9567
            printer.print();
9568
            stream << std::endl;
9569
            return true;
9570
        }
9571
9572
1167
        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
9573
1167
            m_headerPrinted = false;
9574
2334
            StreamingReporterBase::sectionStarting( _sectionInfo );
9575
1167
        }
9576
1167
        virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
9577
1167
            if( _sectionStats.missingAssertions ) {
9578
                lazyPrint();
9579
                Colour colour( Colour::ResultError );
9580
                if( m_sectionStack.size() > 1 )
9581
                    stream << "\nNo assertions in section";
9582
                else
9583
                    stream << "\nNo assertions in test case";
9584
                stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
9585
            }
9586
1167
            if( m_headerPrinted ) {
9587
                if( m_config->showDurations() == ShowDurations::Always )
9588
                    stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9589
                m_headerPrinted = false;
9590
            }
9591
            else {
9592
2334
                if( m_config->showDurations() == ShowDurations::Always )
9593
                    stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9594
            }
9595
2334
            StreamingReporterBase::sectionEnded( _sectionStats );
9596
1167
        }
9597
9598
395
        virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
9599
790
            StreamingReporterBase::testCaseEnded( _testCaseStats );
9600
395
            m_headerPrinted = false;
9601
395
        }
9602
1
        virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
9603
1
            if( currentGroupInfo.used ) {
9604
                printSummaryDivider();
9605
                stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
9606
                printTotals( _testGroupStats.totals );
9607
                stream << "\n" << std::endl;
9608
            }
9609
2
            StreamingReporterBase::testGroupEnded( _testGroupStats );
9610
1
        }
9611
1
        virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
9612
1
            printTotalsDivider( _testRunStats.totals );
9613
1
            printTotals( _testRunStats.totals );
9614
2
            stream << std::endl;
9615
1
            StreamingReporterBase::testRunEnded( _testRunStats );
9616
1
        }
9617
9618
    private:
9619
9620
        class AssertionPrinter {
9621
            void operator= ( AssertionPrinter const& );
9622
        public:
9623
            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
9624
            :   stream( _stream ),
9625
                stats( _stats ),
9626
                result( _stats.assertionResult ),
9627
                colour( Colour::None ),
9628
                message( result.getMessage() ),
9629
                messages( _stats.infoMessages ),
9630
                printInfoMessages( _printInfoMessages )
9631
            {
9632
                switch( result.getResultType() ) {
9633
                    case ResultWas::Ok:
9634
                        colour = Colour::Success;
9635
                        passOrFail = "PASSED";
9636
                        //if( result.hasMessage() )
9637
                        if( _stats.infoMessages.size() == 1 )
9638
                            messageLabel = "with message";
9639
                        if( _stats.infoMessages.size() > 1 )
9640
                            messageLabel = "with messages";
9641
                        break;
9642
                    case ResultWas::ExpressionFailed:
9643
                        if( result.isOk() ) {
9644
                            colour = Colour::Success;
9645
                            passOrFail = "FAILED - but was ok";
9646
                        }
9647
                        else {
9648
                            colour = Colour::Error;
9649
                            passOrFail = "FAILED";
9650
                        }
9651
                        if( _stats.infoMessages.size() == 1 )
9652
                            messageLabel = "with message";
9653
                        if( _stats.infoMessages.size() > 1 )
9654
                            messageLabel = "with messages";
9655
                        break;
9656
                    case ResultWas::ThrewException:
9657
                        colour = Colour::Error;
9658
                        passOrFail = "FAILED";
9659
                        messageLabel = "due to unexpected exception with message";
9660
                        break;
9661
                    case ResultWas::FatalErrorCondition:
9662
                        colour = Colour::Error;
9663
                        passOrFail = "FAILED";
9664
                        messageLabel = "due to a fatal error condition";
9665
                        break;
9666
                    case ResultWas::DidntThrowException:
9667
                        colour = Colour::Error;
9668
                        passOrFail = "FAILED";
9669
                        messageLabel = "because no exception was thrown where one was expected";
9670
                        break;
9671
                    case ResultWas::Info:
9672
                        messageLabel = "info";
9673
                        break;
9674
                    case ResultWas::Warning:
9675
                        messageLabel = "warning";
9676
                        break;
9677
                    case ResultWas::ExplicitFailure:
9678
                        passOrFail = "FAILED";
9679
                        colour = Colour::Error;
9680
                        if( _stats.infoMessages.size() == 1 )
9681
                            messageLabel = "explicitly with message";
9682
                        if( _stats.infoMessages.size() > 1 )
9683
                            messageLabel = "explicitly with messages";
9684
                        break;
9685
                    // These cases are here to prevent compiler warnings
9686
                    case ResultWas::Unknown:
9687
                    case ResultWas::FailureBit:
9688
                    case ResultWas::Exception:
9689
                        passOrFail = "** internal error **";
9690
                        colour = Colour::Error;
9691
                        break;
9692
                }
9693
            }
9694
9695
            void print() const {
9696
                printSourceInfo();
9697
                if( stats.totals.assertions.total() > 0 ) {
9698
                    if( result.isOk() )
9699
                        stream << "\n";
9700
                    printResultType();
9701
                    printOriginalExpression();
9702
                    printReconstructedExpression();
9703
                }
9704
                else {
9705
                    stream << "\n";
9706
                }
9707
                printMessage();
9708
            }
9709
9710
        private:
9711
            void printResultType() const {
9712
                if( !passOrFail.empty() ) {
9713
                    Colour colourGuard( colour );
9714
                    stream << passOrFail << ":\n";
9715
                }
9716
            }
9717
            void printOriginalExpression() const {
9718
                if( result.hasExpression() ) {
9719
                    Colour colourGuard( Colour::OriginalExpression );
9720
                    stream  << "  ";
9721
                    stream << result.getExpressionInMacro();
9722
                    stream << "\n";
9723
                }
9724
            }
9725
            void printReconstructedExpression() const {
9726
                if( result.hasExpandedExpression() ) {
9727
                    stream << "with expansion:\n";
9728
                    Colour colourGuard( Colour::ReconstructedExpression );
9729
                    stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
9730
                }
9731
            }
9732
            void printMessage() const {
9733
                if( !messageLabel.empty() )
9734
                    stream << messageLabel << ":" << "\n";
9735
                for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
9736
                        it != itEnd;
9737
                        ++it ) {
9738
                    // If this assertion is a warning ignore any INFO messages
9739
                    if( printInfoMessages || it->type != ResultWas::Info )
9740
                        stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
9741
                }
9742
            }
9743
            void printSourceInfo() const {
9744
                Colour colourGuard( Colour::FileName );
9745
                stream << result.getSourceInfo() << ": ";
9746
            }
9747
9748
            std::ostream& stream;
9749
            AssertionStats const& stats;
9750
            AssertionResult const& result;
9751
            Colour::Code colour;
9752
            std::string passOrFail;
9753
            std::string messageLabel;
9754
            std::string message;
9755
            std::vector<MessageInfo> messages;
9756
            bool printInfoMessages;
9757
        };
9758
9759
        void lazyPrint() {
9760
9761
            if( !currentTestRunInfo.used )
9762
                lazyPrintRunInfo();
9763
            if( !currentGroupInfo.used )
9764
                lazyPrintGroupInfo();
9765
9766
            if( !m_headerPrinted ) {
9767
                printTestCaseAndSectionHeader();
9768
                m_headerPrinted = true;
9769
            }
9770
        }
9771
        void lazyPrintRunInfo() {
9772
            stream  << "\n" << getLineOfChars<'~'>() << "\n";
9773
            Colour colour( Colour::SecondaryText );
9774
            stream  << currentTestRunInfo->name
9775
                    << " is a Catch v"  << libraryVersion << " host application.\n"
9776
                    << "Run with -? for options\n\n";
9777
9778
            if( m_config->rngSeed() != 0 )
9779
                stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
9780
9781
            currentTestRunInfo.used = true;
9782
        }
9783
        void lazyPrintGroupInfo() {
9784
            if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
9785
                printClosedHeader( "Group: " + currentGroupInfo->name );
9786
                currentGroupInfo.used = true;
9787
            }
9788
        }
9789
        void printTestCaseAndSectionHeader() {
9790
            assert( !m_sectionStack.empty() );
9791
            printOpenHeader( currentTestCaseInfo->name );
9792
9793
            if( m_sectionStack.size() > 1 ) {
9794
                Colour colourGuard( Colour::Headers );
9795
9796
                std::vector<SectionInfo>::const_iterator
9797
                    it = m_sectionStack.begin()+1, // Skip first section (test case)
9798
                    itEnd = m_sectionStack.end();
9799
                for( ; it != itEnd; ++it )
9800
                    printHeaderString( it->name, 2 );
9801
            }
9802
9803
            SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
9804
9805
            if( !lineInfo.empty() ){
9806
                stream << getLineOfChars<'-'>() << "\n";
9807
                Colour colourGuard( Colour::FileName );
9808
                stream << lineInfo << "\n";
9809
            }
9810
            stream << getLineOfChars<'.'>() << "\n" << std::endl;
9811
        }
9812
9813
        void printClosedHeader( std::string const& _name ) {
9814
            printOpenHeader( _name );
9815
            stream << getLineOfChars<'.'>() << "\n";
9816
        }
9817
        void printOpenHeader( std::string const& _name ) {
9818
            stream  << getLineOfChars<'-'>() << "\n";
9819
            {
9820
                Colour colourGuard( Colour::Headers );
9821
                printHeaderString( _name );
9822
            }
9823
        }
9824
9825
        // if string has a : in first line will set indent to follow it on
9826
        // subsequent lines
9827
        void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
9828
            std::size_t i = _string.find( ": " );
9829
            if( i != std::string::npos )
9830
                i+=2;
9831
            else
9832
                i = 0;
9833
            stream << Text( _string, TextAttributes()
9834
                                        .setIndent( indent+i)
9835
                                        .setInitialIndent( indent ) ) << "\n";
9836
        }
9837
9838
        struct SummaryColumn {
9839
9840
            SummaryColumn( std::string const& _label, Colour::Code _colour )
9841
            :   label( _label ),
9842
                colour( _colour )
9843
            {}
9844
            SummaryColumn addRow( std::size_t count ) {
9845
                std::ostringstream oss;
9846
                oss << count;
9847
                std::string row = oss.str();
9848
                for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
9849
                    while( it->size() < row.size() )
9850
                        *it = " " + *it;
9851
                    while( it->size() > row.size() )
9852
                        row = " " + row;
9853
                }
9854
                rows.push_back( row );
9855
                return *this;
9856
            }
9857
9858
            std::string label;
9859
            Colour::Code colour;
9860
            std::vector<std::string> rows;
9861
9862
        };
9863
9864
1
        void printTotals( Totals const& totals ) {
9865
2
            if( totals.testCases.total() == 0 ) {
9866
                stream << Colour( Colour::Warning ) << "No tests ran\n";
9867
            }
9868

3
            else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
9869
2
                stream << Colour( Colour::ResultSuccess ) << "All tests passed";
9870
2
                stream << " ("
9871

8
                        << pluralise( totals.assertions.passed, "assertion" ) << " in "
9872
7
                        << pluralise( totals.testCases.passed, "test case" ) << ")"
9873
1
                        << "\n";
9874
            }
9875
            else {
9876
9877
                std::vector<SummaryColumn> columns;
9878
                columns.push_back( SummaryColumn( "", Colour::None )
9879
                                        .addRow( totals.testCases.total() )
9880
                                        .addRow( totals.assertions.total() ) );
9881
                columns.push_back( SummaryColumn( "passed", Colour::Success )
9882
                                        .addRow( totals.testCases.passed )
9883
                                        .addRow( totals.assertions.passed ) );
9884
                columns.push_back( SummaryColumn( "failed", Colour::ResultError )
9885
                                        .addRow( totals.testCases.failed )
9886
                                        .addRow( totals.assertions.failed ) );
9887
                columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
9888
                                        .addRow( totals.testCases.failedButOk )
9889
                                        .addRow( totals.assertions.failedButOk ) );
9890
9891
                printSummaryRow( "test cases", columns, 0 );
9892
                printSummaryRow( "assertions", columns, 1 );
9893
            }
9894
1
        }
9895
        void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
9896
            for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
9897
                std::string value = it->rows[row];
9898
                if( it->label.empty() ) {
9899
                    stream << label << ": ";
9900
                    if( value != "0" )
9901
                        stream << value;
9902
                    else
9903
                        stream << Colour( Colour::Warning ) << "- none -";
9904
                }
9905
                else if( value != "0" ) {
9906
                    stream  << Colour( Colour::LightGrey ) << " | ";
9907
                    stream  << Colour( it->colour )
9908
                            << value << " " << it->label;
9909
                }
9910
            }
9911
            stream << "\n";
9912
        }
9913
9914
        static std::size_t makeRatio( std::size_t number, std::size_t total ) {
9915
3
            std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
9916

3
            return ( ratio == 0 && number > 0 ) ? 1 : ratio;
9917
        }
9918
        static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
9919


1
            if( i > j && i > k )
9920
                return i;
9921

1
            else if( j > k )
9922
                return j;
9923
            else
9924
                return k;
9925
        }
9926
9927
1
        void printTotalsDivider( Totals const& totals ) {
9928
2
            if( totals.testCases.total() > 0 ) {
9929
2
                std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
9930
2
                std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
9931
2
                std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
9932
1
                while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
9933
                    findMax( failedRatio, failedButOkRatio, passedRatio )++;
9934
3
                while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
9935
1
                    findMax( failedRatio, failedButOkRatio, passedRatio )--;
9936
9937
8
                stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
9938
8
                stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
9939
2
                if( totals.testCases.allPassed() )
9940
8
                    stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
9941
                else
9942
                    stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
9943
            }
9944
            else {
9945
                stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
9946
            }
9947
1
            stream << "\n";
9948
1
        }
9949
        void printSummaryDivider() {
9950
            stream << getLineOfChars<'-'>() << "\n";
9951
        }
9952
9953
    private:
9954
        bool m_headerPrinted;
9955
    };
9956
9957
4
    INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
9958
9959
} // end namespace Catch
9960
9961
// #included from: ../reporters/catch_reporter_compact.hpp
9962
#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
9963
9964
namespace Catch {
9965
9966
    struct CompactReporter : StreamingReporterBase {
9967
9968
        CompactReporter( ReporterConfig const& _config )
9969
        : StreamingReporterBase( _config )
9970
        {}
9971
9972
        virtual ~CompactReporter();
9973
9974
        static std::string getDescription() {
9975
            return "Reports test results on a single line, suitable for IDEs";
9976
        }
9977
9978
        virtual ReporterPreferences getPreferences() const {
9979
            ReporterPreferences prefs;
9980
            prefs.shouldRedirectStdOut = false;
9981
            return prefs;
9982
        }
9983
9984
        virtual void noMatchingTestCases( std::string const& spec ) {
9985
            stream << "No test cases matched '" << spec << "'" << std::endl;
9986
        }
9987
9988
        virtual void assertionStarting( AssertionInfo const& ) {
9989
        }
9990
9991
        virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
9992
            AssertionResult const& result = _assertionStats.assertionResult;
9993
9994
            bool printInfoMessages = true;
9995
9996
            // Drop out if result was successful and we're not printing those
9997
            if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9998
                if( result.getResultType() != ResultWas::Warning )
9999
                    return false;
10000
                printInfoMessages = false;
10001
            }
10002
10003
            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
10004
            printer.print();
10005
10006
            stream << std::endl;
10007
            return true;
10008
        }
10009
10010
        virtual void testRunEnded( TestRunStats const& _testRunStats ) {
10011
            printTotals( _testRunStats.totals );
10012
            stream << "\n" << std::endl;
10013
            StreamingReporterBase::testRunEnded( _testRunStats );
10014
        }
10015
10016
    private:
10017
        class AssertionPrinter {
10018
            void operator= ( AssertionPrinter const& );
10019
        public:
10020
            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
10021
            : stream( _stream )
10022
            , stats( _stats )
10023
            , result( _stats.assertionResult )
10024
            , messages( _stats.infoMessages )
10025
            , itMessage( _stats.infoMessages.begin() )
10026
            , printInfoMessages( _printInfoMessages )
10027
            {}
10028
10029
            void print() {
10030
                printSourceInfo();
10031
10032
                itMessage = messages.begin();
10033
10034
                switch( result.getResultType() ) {
10035
                    case ResultWas::Ok:
10036
                        printResultType( Colour::ResultSuccess, passedString() );
10037
                        printOriginalExpression();
10038
                        printReconstructedExpression();
10039
                        if ( ! result.hasExpression() )
10040
                            printRemainingMessages( Colour::None );
10041
                        else
10042
                            printRemainingMessages();
10043
                        break;
10044
                    case ResultWas::ExpressionFailed:
10045
                        if( result.isOk() )
10046
                            printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
10047
                        else
10048
                            printResultType( Colour::Error, failedString() );
10049
                        printOriginalExpression();
10050
                        printReconstructedExpression();
10051
                        printRemainingMessages();
10052
                        break;
10053
                    case ResultWas::ThrewException:
10054
                        printResultType( Colour::Error, failedString() );
10055
                        printIssue( "unexpected exception with message:" );
10056
                        printMessage();
10057
                        printExpressionWas();
10058
                        printRemainingMessages();
10059
                        break;
10060
                    case ResultWas::FatalErrorCondition:
10061
                        printResultType( Colour::Error, failedString() );
10062
                        printIssue( "fatal error condition with message:" );
10063
                        printMessage();
10064
                        printExpressionWas();
10065
                        printRemainingMessages();
10066
                        break;
10067
                    case ResultWas::DidntThrowException:
10068
                        printResultType( Colour::Error, failedString() );
10069
                        printIssue( "expected exception, got none" );
10070
                        printExpressionWas();
10071
                        printRemainingMessages();
10072
                        break;
10073
                    case ResultWas::Info:
10074
                        printResultType( Colour::None, "info" );
10075
                        printMessage();
10076
                        printRemainingMessages();
10077
                        break;
10078
                    case ResultWas::Warning:
10079
                        printResultType( Colour::None, "warning" );
10080
                        printMessage();
10081
                        printRemainingMessages();
10082
                        break;
10083
                    case ResultWas::ExplicitFailure:
10084
                        printResultType( Colour::Error, failedString() );
10085
                        printIssue( "explicitly" );
10086
                        printRemainingMessages( Colour::None );
10087
                        break;
10088
                    // These cases are here to prevent compiler warnings
10089
                    case ResultWas::Unknown:
10090
                    case ResultWas::FailureBit:
10091
                    case ResultWas::Exception:
10092
                        printResultType( Colour::Error, "** internal error **" );
10093
                        break;
10094
                }
10095
            }
10096
10097
        private:
10098
            // Colour::LightGrey
10099
10100
            static Colour::Code dimColour() { return Colour::FileName; }
10101
10102
#ifdef CATCH_PLATFORM_MAC
10103
            static const char* failedString() { return "FAILED"; }
10104
            static const char* passedString() { return "PASSED"; }
10105
#else
10106
            static const char* failedString() { return "failed"; }
10107
            static const char* passedString() { return "passed"; }
10108
#endif
10109
10110
            void printSourceInfo() const {
10111
                Colour colourGuard( Colour::FileName );
10112
                stream << result.getSourceInfo() << ":";
10113
            }
10114
10115
            void printResultType( Colour::Code colour, std::string passOrFail ) const {
10116
                if( !passOrFail.empty() ) {
10117
                    {
10118
                        Colour colourGuard( colour );
10119
                        stream << " " << passOrFail;
10120
                    }
10121
                    stream << ":";
10122
                }
10123
            }
10124
10125
            void printIssue( std::string issue ) const {
10126
                stream << " " << issue;
10127
            }
10128
10129
            void printExpressionWas() {
10130
                if( result.hasExpression() ) {
10131
                    stream << ";";
10132
                    {
10133
                        Colour colour( dimColour() );
10134
                        stream << " expression was:";
10135
                    }
10136
                    printOriginalExpression();
10137
                }
10138
            }
10139
10140
            void printOriginalExpression() const {
10141
                if( result.hasExpression() ) {
10142
                    stream << " " << result.getExpression();
10143
                }
10144
            }
10145
10146
            void printReconstructedExpression() const {
10147
                if( result.hasExpandedExpression() ) {
10148
                    {
10149
                        Colour colour( dimColour() );
10150
                        stream << " for: ";
10151
                    }
10152
                    stream << result.getExpandedExpression();
10153
                }
10154
            }
10155
10156
            void printMessage() {
10157
                if ( itMessage != messages.end() ) {
10158
                    stream << " '" << itMessage->message << "'";
10159
                    ++itMessage;
10160
                }
10161
            }
10162
10163
            void printRemainingMessages( Colour::Code colour = dimColour() ) {
10164
                if ( itMessage == messages.end() )
10165
                    return;
10166
10167
                // using messages.end() directly yields compilation error:
10168
                std::vector<MessageInfo>::const_iterator itEnd = messages.end();
10169
                const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
10170
10171
                {
10172
                    Colour colourGuard( colour );
10173
                    stream << " with " << pluralise( N, "message" ) << ":";
10174
                }
10175
10176
                for(; itMessage != itEnd; ) {
10177
                    // If this assertion is a warning ignore any INFO messages
10178
                    if( printInfoMessages || itMessage->type != ResultWas::Info ) {
10179
                        stream << " '" << itMessage->message << "'";
10180
                        if ( ++itMessage != itEnd ) {
10181
                            Colour colourGuard( dimColour() );
10182
                            stream << " and";
10183
                        }
10184
                    }
10185
                }
10186
            }
10187
10188
        private:
10189
            std::ostream& stream;
10190
            AssertionStats const& stats;
10191
            AssertionResult const& result;
10192
            std::vector<MessageInfo> messages;
10193
            std::vector<MessageInfo>::const_iterator itMessage;
10194
            bool printInfoMessages;
10195
        };
10196
10197
        // Colour, message variants:
10198
        // - white: No tests ran.
10199
        // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
10200
        // - white: Passed [both/all] N test cases (no assertions).
10201
        // -   red: Failed N tests cases, failed M assertions.
10202
        // - green: Passed [both/all] N tests cases with M assertions.
10203
10204
        std::string bothOrAll( std::size_t count ) const {
10205
            return count == 1 ? "" : count == 2 ? "both " : "all " ;
10206
        }
10207
10208
        void printTotals( const Totals& totals ) const {
10209
            if( totals.testCases.total() == 0 ) {
10210
                stream << "No tests ran.";
10211
            }
10212
            else if( totals.testCases.failed == totals.testCases.total() ) {
10213
                Colour colour( Colour::ResultError );
10214
                const std::string qualify_assertions_failed =
10215
                    totals.assertions.failed == totals.assertions.total() ?
10216
                        bothOrAll( totals.assertions.failed ) : "";
10217
                stream <<
10218
                    "Failed " << bothOrAll( totals.testCases.failed )
10219
                              << pluralise( totals.testCases.failed, "test case"  ) << ", "
10220
                    "failed " << qualify_assertions_failed <<
10221
                                 pluralise( totals.assertions.failed, "assertion" ) << ".";
10222
            }
10223
            else if( totals.assertions.total() == 0 ) {
10224
                stream <<
10225
                    "Passed " << bothOrAll( totals.testCases.total() )
10226
                              << pluralise( totals.testCases.total(), "test case" )
10227
                              << " (no assertions).";
10228
            }
10229
            else if( totals.assertions.failed ) {
10230
                Colour colour( Colour::ResultError );
10231
                stream <<
10232
                    "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
10233
                    "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
10234
            }
10235
            else {
10236
                Colour colour( Colour::ResultSuccess );
10237
                stream <<
10238
                    "Passed " << bothOrAll( totals.testCases.passed )
10239
                              << pluralise( totals.testCases.passed, "test case"  ) <<
10240
                    " with "  << pluralise( totals.assertions.passed, "assertion" ) << ".";
10241
            }
10242
        }
10243
    };
10244
10245
4
    INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
10246
10247
} // end namespace Catch
10248
10249
namespace Catch {
10250
    // These are all here to avoid warnings about not having any out of line
10251
    // virtual methods
10252
    NonCopyable::~NonCopyable() {}
10253
1635
    IShared::~IShared() {}
10254
    IStream::~IStream() CATCH_NOEXCEPT {}
10255
    FileStream::~FileStream() CATCH_NOEXCEPT {}
10256
2
    CoutStream::~CoutStream() CATCH_NOEXCEPT {}
10257
    DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
10258
    StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
10259
    IContext::~IContext() {}
10260
    IResultCapture::~IResultCapture() {}
10261
790
    ITestCase::~ITestCase() {}
10262
    ITestCaseRegistry::~ITestCaseRegistry() {}
10263
    IRegistryHub::~IRegistryHub() {}
10264
    IMutableRegistryHub::~IMutableRegistryHub() {}
10265
    IExceptionTranslator::~IExceptionTranslator() {}
10266
    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
10267
    IReporter::~IReporter() {}
10268
8
    IReporterFactory::~IReporterFactory() {}
10269
    IReporterRegistry::~IReporterRegistry() {}
10270
2
    IStreamingReporter::~IStreamingReporter() {}
10271
2866004
    AssertionStats::~AssertionStats() {}
10272
1167
    SectionStats::~SectionStats() {}
10273
1185
    TestCaseStats::~TestCaseStats() {}
10274
2
    TestGroupStats::~TestGroupStats() {}
10275
2
    TestRunStats::~TestRunStats() {}
10276
    CumulativeReporterBase::SectionNode::~SectionNode() {}
10277
    CumulativeReporterBase::~CumulativeReporterBase() {}
10278
10279
6
    StreamingReporterBase::~StreamingReporterBase() {}
10280
1
    ConsoleReporter::~ConsoleReporter() {}
10281
    CompactReporter::~CompactReporter() {}
10282
    IRunner::~IRunner() {}
10283
1
    IMutableContext::~IMutableContext() {}
10284
2
    IConfig::~IConfig() {}
10285
    XmlReporter::~XmlReporter() {}
10286
    JunitReporter::~JunitReporter() {}
10287
1
    TestRegistry::~TestRegistry() {}
10288
790
    FreeFunctionTestCase::~FreeFunctionTestCase() {}
10289
    IGeneratorInfo::~IGeneratorInfo() {}
10290
    IGeneratorsForTest::~IGeneratorsForTest() {}
10291
    WildcardPattern::~WildcardPattern() {}
10292
4
    TestSpec::Pattern::~Pattern() {}
10293
    TestSpec::NamePattern::~NamePattern() {}
10294
3
    TestSpec::TagPattern::~TagPattern() {}
10295
3
    TestSpec::ExcludedPattern::~ExcludedPattern() {}
10296
10297
    Matchers::Impl::StdString::Equals::~Equals() {}
10298
    Matchers::Impl::StdString::Contains::~Contains() {}
10299
    Matchers::Impl::StdString::StartsWith::~StartsWith() {}
10300
    Matchers::Impl::StdString::EndsWith::~EndsWith() {}
10301
10302
    void Config::dummy() {}
10303
10304
    namespace TestCaseTracking {
10305
2402
        ITracker::~ITracker() {}
10306
3603
        TrackerBase::~TrackerBase() {}
10307
1201
        SectionTracker::~SectionTracker() {}
10308
        IndexTracker::~IndexTracker() {}
10309
    }
10310
}
10311
10312
#ifdef __clang__
10313
#pragma clang diagnostic pop
10314
#endif
10315
10316
#endif
10317
10318
#ifdef CATCH_CONFIG_MAIN
10319
// #included from: internal/catch_default_main.hpp
10320
#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
10321
10322
#ifndef __OBJC__
10323
10324
// Standard C/C++ main entry point
10325
int main (int argc, char * argv[]) {
10326
    return Catch::Session().run( argc, argv );
10327
}
10328
10329
#else // __OBJC__
10330
10331
// Objective-C entry point
10332
int main (int argc, char * const argv[]) {
10333
#if !CATCH_ARC_ENABLED
10334
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
10335
#endif
10336
10337
    Catch::registerTestMethods();
10338
    int result = Catch::Session().run( argc, (char* const*)argv );
10339
10340
#if !CATCH_ARC_ENABLED
10341
    [pool drain];
10342
#endif
10343
10344
    return result;
10345
}
10346
10347
#endif // __OBJC__
10348
10349
#endif
10350
10351
#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
10352
#  undef CLARA_CONFIG_MAIN
10353
#endif
10354
10355
//////
10356
10357
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
10358
#ifdef CATCH_CONFIG_PREFIX_ALL
10359
10360
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
10361
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
10362
10363
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
10364
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
10365
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
10366
#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
10367
10368
#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
10369
#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
10370
#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
10371
#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
10372
#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
10373
10374
#define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
10375
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
10376
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
10377
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
10378
10379
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
10380
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
10381
10382
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10383
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
10384
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10385
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10386
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10387
10388
#ifdef CATCH_CONFIG_VARIADIC_MACROS
10389
    #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10390
    #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10391
    #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10392
    #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
10393
    #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10394
    #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
10395
    #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
10396
#else
10397
    #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10398
    #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10399
    #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10400
    #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
10401
    #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10402
    #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
10403
    #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
10404
#endif
10405
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10406
10407
#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10408
#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10409
10410
#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10411
10412
// "BDD-style" convenience wrappers
10413
#ifdef CATCH_CONFIG_VARIADIC_MACROS
10414
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
10415
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10416
#else
10417
#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
10418
#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10419
#endif
10420
#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
10421
#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
10422
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
10423
#define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
10424
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
10425
10426
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
10427
#else
10428
10429
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
10430
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
10431
10432
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
10433
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
10434
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
10435
#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
10436
10437
#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
10438
#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
10439
#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
10440
#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
10441
#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
10442
10443
#define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
10444
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
10445
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
10446
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
10447
10448
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
10449
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
10450
10451
#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10452
#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
10453
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10454
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10455
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10456
10457
#ifdef CATCH_CONFIG_VARIADIC_MACROS
10458
    #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10459
    #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10460
    #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10461
    #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
10462
    #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10463
    #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
10464
    #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
10465
#else
10466
    #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10467
    #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10468
    #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10469
    #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
10470
    #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10471
    #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
10472
    #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
10473
#endif
10474
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10475
10476
#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10477
#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10478
10479
#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10480
10481
#endif
10482
10483
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
10484
10485
// "BDD-style" convenience wrappers
10486
#ifdef CATCH_CONFIG_VARIADIC_MACROS
10487
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
10488
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10489
#else
10490
#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
10491
#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10492
#endif
10493
#define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
10494
#define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
10495
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
10496
#define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
10497
#define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
10498
10499
using Catch::Detail::Approx;
10500
10501
#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
10502