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