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