| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  Created by Phil on 14/01/2011. | 
					
						
							|  |  |  |  *  Copyright 2011 Two Blue Cubes Ltd. All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | 
					
						
							|  |  |  |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #ifndef TWOBLUECUBES_CATCH_SELF_TEST_HPP_INCLUDED
 | 
					
						
							|  |  |  | #define TWOBLUECUBES_CATCH_SELF_TEST_HPP_INCLUDED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 08:23:02 +01:00
										 |  |  | #include "catch.hpp"
 | 
					
						
							| 
									
										
										
										
											2012-08-09 07:47:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Use this external guard here as if we're using the single header version
 | 
					
						
							|  |  |  | // this will already be defined
 | 
					
						
							|  |  |  | #ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
 | 
					
						
							| 
									
										
										
										
											2012-08-07 07:58:34 +01:00
										 |  |  | #include "catch_interfaces_registry_hub.h"
 | 
					
						
							| 
									
										
										
										
											2012-08-09 07:47:30 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  | #include "set"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  | namespace Catch { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |     class MockReporter : public SharedImpl<IReporter> { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |     public: | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         static const std::string recordGroups; | 
					
						
							|  |  |  |         static const std::string recordTestCases; | 
					
						
							|  |  |  |         static const std::string recordSections; | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         void recordAll() { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             addRecorder( recordGroups ); | 
					
						
							|  |  |  |             addRecorder( recordTestCases ); | 
					
						
							|  |  |  |             addRecorder( recordSections ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |                  | 
					
						
							| 
									
										
										
										
											2012-07-20 19:07:42 +01:00
										 |  |  |         MockReporter( const ReporterConfig& ) { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             recordAll(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         MockReporter() { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             recordAll(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         void addRecorder( const std::string& recorder ) { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             m_recorders.insert( recorder ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         static std::string getDescription() { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             return "mock reporter"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         std::string getLog() const { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             return m_log.str(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     private: // IReporter
 | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         virtual bool shouldRedirectStdout() const { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         virtual void StartTesting() {} | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-24 08:23:55 +01:00
										 |  |  |         virtual void EndTesting( const Totals& ) {} | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         virtual void StartGroup( const std::string& groupName ) { | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |             openLabel( recordGroups, groupName ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-24 08:23:55 +01:00
										 |  |  |         virtual void EndGroup( const std::string& groupName, const Totals& ) { | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |             closeLabel( recordGroups, groupName ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-24 08:23:55 +01:00
										 |  |  |         virtual void StartSection( const std::string& sectionName, const std::string& ) { | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |             openLabel( recordSections, sectionName ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-08-31 08:10:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         virtual void NoAssertionsInSection( const std::string& ) {} | 
					
						
							|  |  |  |         virtual void NoAssertionsInTestCase( const std::string& ) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-24 08:23:55 +01:00
										 |  |  |         virtual void EndSection( const std::string& sectionName, const Counts& ) { | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |             closeLabel( recordSections, sectionName ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         virtual void StartTestCase( const TestCaseInfo& testInfo ) { | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |             openLabel( recordTestCases, testInfo.getName()  ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-06-01 19:40:27 +01:00
										 |  |  |         virtual void Aborted(){} | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         virtual void EndTestCase(   const TestCaseInfo& testInfo,  | 
					
						
							| 
									
										
										
										
											2012-05-24 08:23:55 +01:00
										 |  |  |                                     const Totals&, | 
					
						
							|  |  |  |                                     const std::string&,  | 
					
						
							|  |  |  |                                     const std::string& ) { | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |             closeLabel( recordTestCases, testInfo.getName()  ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-10-16 08:31:05 +01:00
										 |  |  |         virtual void Result( const AssertionResult& assertionResult ); | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         bool shouldRecord( const std::string& recorder ) const { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             return m_recorders.find( recorder ) != m_recorders.end(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-07 18:59:33 +01:00
										 |  |  |         void openLabel( const std::string& label, const std::string& arg = "" ); | 
					
						
							|  |  |  |         void closeLabel( const std::string& label, const std::string& arg = "" ); | 
					
						
							| 
									
										
										
										
											2012-05-05 19:32:52 +01:00
										 |  |  |          | 
					
						
							|  |  |  |         std::string m_indent; | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         std::ostringstream m_log; | 
					
						
							|  |  |  |         std::set<std::string> m_recorders; | 
					
						
							| 
									
										
										
										
											2012-05-31 19:40:26 +01:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |     class EmbeddedRunner { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         EmbeddedRunner() : m_reporter( new MockReporter() ) {} | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-08-15 19:12:51 +01:00
										 |  |  |         Totals runMatching( const std::string& rawTestSpec, | 
					
						
							|  |  |  |                             const std::string& reporter = "basic" ); | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         std::string getOutput() { | 
					
						
							| 
									
										
										
										
											2011-02-09 09:08:10 +00:00
										 |  |  |             return m_output; | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-05-31 19:40:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         void addRecorder( const std::string& recorder ) { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             m_reporter->addRecorder( recorder ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         std::string getLog() const { | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |             return m_reporter->getLog(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-05-31 19:40:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  |     private: | 
					
						
							| 
									
										
										
										
											2011-02-09 09:08:10 +00:00
										 |  |  |         std::string m_output; | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |         Ptr<MockReporter> m_reporter; | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |     class MetaTestRunner { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         struct Expected { enum Result { | 
					
						
							|  |  |  |             ToSucceed, | 
					
						
							|  |  |  |             ToFail | 
					
						
							|  |  |  |         }; }; | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         MetaTestRunner( Expected::Result expectedResult ) : m_expectedResult( expectedResult ) {} | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         static void runMatching(    const std::string& testSpec,  | 
					
						
							|  |  |  |                                     Expected::Result expectedResult ) { | 
					
						
							| 
									
										
										
										
											2012-08-07 07:58:34 +01:00
										 |  |  |             forEach(    getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec ),  | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |                         MetaTestRunner( expectedResult ) ); | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         void operator()( const TestCaseInfo& testCase ) { | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |             EmbeddedRunner runner; | 
					
						
							| 
									
										
										
										
											2012-08-15 19:12:51 +01:00
										 |  |  |             Totals totals = runner.runMatching( testCase.getName() ); | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |             switch( m_expectedResult ) { | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                 case Expected::ToSucceed: | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |                     if( totals.assertions.failed > 0 ) { | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                         INFO( runner.getOutput() ); | 
					
						
							|  |  |  |                         FAIL( "Expected test case '"  | 
					
						
							|  |  |  |                              << testCase.getName()  | 
					
						
							|  |  |  |                              << "' to succeed but there was/ were "  | 
					
						
							| 
									
										
										
										
											2012-02-23 18:51:21 +00:00
										 |  |  |                              << totals.assertions.failed << " failure(s)" ); | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2012-08-31 08:10:36 +01:00
										 |  |  |                     else { | 
					
						
							|  |  |  |                         SUCCEED( "Tests passed, as expected" ); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case Expected::ToFail: | 
					
						
							| 
									
										
										
										
											2012-11-19 19:59:10 +00:00
										 |  |  |                     if( totals.assertions.failed == 0 ) { | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                         INFO( runner.getOutput() ); | 
					
						
							|  |  |  |                         FAIL( "Expected test case '"  | 
					
						
							|  |  |  |                              << testCase.getName()  | 
					
						
							|  |  |  |                              << "' to fail but there was/ were "  | 
					
						
							| 
									
										
										
										
											2012-02-23 18:51:21 +00:00
										 |  |  |                              << totals.assertions.passed << " success(es)" ); | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2012-08-31 08:10:36 +01:00
										 |  |  |                     else { | 
					
						
							|  |  |  |                         SUCCEED( "Tests failed, as expected" ); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2011-03-11 19:44:59 +00:00
										 |  |  |                     break; | 
					
						
							|  |  |  |             }         | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         Expected::Result m_expectedResult; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |     struct LineInfoRegistry { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static LineInfoRegistry& get() { | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  |             static LineInfoRegistry s_instance; | 
					
						
							|  |  |  |             return s_instance; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         void registerLineInfo(  const std::string& name,  | 
					
						
							|  |  |  |                                 const SourceLineInfo& info ) { | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  |             m_registry.insert( std::make_pair( name, info ) ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         const SourceLineInfo* find( const std::string& name ) const { | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  |             std::map<std::string, SourceLineInfo>::const_iterator it = m_registry.find( name ); | 
					
						
							|  |  |  |             return it == m_registry.end() ? NULL : &(it->second); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |         const std::string infoForName( const std::string& name ) const { | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  |             std::map<std::string, SourceLineInfo>::const_iterator it = m_registry.find( name ); | 
					
						
							|  |  |  |             if( it == m_registry.end() ) | 
					
						
							|  |  |  |                 return ""; | 
					
						
							|  |  |  |             std::ostringstream oss; | 
					
						
							|  |  |  |             oss << it->second; | 
					
						
							|  |  |  |             return oss.str(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         std::map<std::string, SourceLineInfo> m_registry; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2012-05-16 15:02:51 +01:00
										 |  |  |     struct LineInfoRegistrar { | 
					
						
							|  |  |  |         LineInfoRegistrar( const char* name, const SourceLineInfo& lineInfo ) { | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  |             LineInfoRegistry::get().registerLineInfo( name, lineInfo ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2012-05-04 07:55:11 +01:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 08:20:06 +00:00
										 |  |  | #define CATCH_REGISTER_LINE_INFO( name ) ::Catch::LineInfoRegistrar INTERNAL_CATCH_UNIQUE_NAME( lineRegistrar )( name, ::Catch::SourceLineInfo( __FILE__, __LINE__ ) );
 | 
					
						
							|  |  |  | #define CATCH_GET_LINE_INFO( name ) ::Catch::LineInfoRegistry::get().infoForName( name )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-14 08:38:46 +00:00
										 |  |  | #endif // TWOBLUECUBES_CATCH_SELF_TEST_HPP_INCLUDED
 |