mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-30 19:57:10 +01:00 
			
		
		
		
	Tags beginning with a non alpha-numeric character are now disallowed.
Added !throws special tag which denotes a test case to be skipped when run with -e (the idea being that the test case is expected to throw an exception which is not caught within a XXX_THROWS assertion).
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
|  | ||||
|  | ||||
| *v1.0 build 35 (master branch)* | ||||
| *v1.0 build 36 (master branch)* | ||||
|  | ||||
| Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch) | ||||
|  | ||||
|   | ||||
| @@ -50,14 +50,16 @@ namespace Catch { | ||||
|             } | ||||
|             return totals; | ||||
|         } | ||||
|  | ||||
|         Totals runTestsForGroup( RunContext& context, const TestCaseFilters& filterGroup ) { | ||||
|         Totals runTestsForGroup( RunContext& context, TestCaseFilters const& filterGroup ) { | ||||
|             Totals totals; | ||||
|             std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end(); | ||||
|  | ||||
|             std::vector<TestCase> testCases; | ||||
|             getRegistryHub().getTestCaseRegistry().getFilteredTests( filterGroup, *m_config, testCases ); | ||||
|  | ||||
|             int testsRunForGroup = 0; | ||||
|             for(; it != itEnd; ++it ) { | ||||
|                 if( filterGroup.shouldInclude( *it ) ) { | ||||
|             for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) { | ||||
|                 testsRunForGroup++; | ||||
|                 if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) { | ||||
|  | ||||
| @@ -68,11 +70,9 @@ namespace Catch { | ||||
|                     m_testsAlreadyRun.insert( *it ); | ||||
|                 } | ||||
|             } | ||||
|             } | ||||
|             if( testsRunForGroup == 0 && !filterGroup.getName().empty() ) | ||||
|                 m_reporter->noMatchingTestCases( filterGroup.getName() ); | ||||
|             return totals; | ||||
|  | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -58,7 +58,7 @@ namespace Catch { | ||||
|         static void use( Code _colourCode ); | ||||
|  | ||||
|     private: | ||||
|         static Detail::IColourImpl* impl; | ||||
|         static Detail::IColourImpl* impl(); | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|   | ||||
| @@ -73,7 +73,10 @@ namespace { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     Win32ColourImpl platformColourImpl; | ||||
|     static Detail::IColourImpl* platformColourInstance() { | ||||
|         static Win32ColourImpl s_instance; | ||||
|         return &s_instance; | ||||
|     } | ||||
|  | ||||
| } // end anon namespace | ||||
| } // end namespace Catch | ||||
| @@ -120,7 +123,10 @@ namespace { | ||||
|         return isatty(STDOUT_FILENO); | ||||
|     } | ||||
|  | ||||
|     PosixColourImpl platformColourImpl; | ||||
|     static Detail::IColourImpl* platformColourInstance() { | ||||
|         static PosixColourImpl s_instance; | ||||
|         return &s_instance; | ||||
|     } | ||||
|  | ||||
| } // end anon namespace | ||||
| } // end namespace Catch | ||||
| @@ -132,21 +138,28 @@ namespace Catch { | ||||
|     namespace { | ||||
|         struct NoColourImpl : Detail::IColourImpl { | ||||
|             void use( Colour::Code ) {} | ||||
|  | ||||
|             static IColourImpl* instance() { | ||||
|                 static NoColourImpl s_instance; | ||||
|                 return &s_instance; | ||||
|             } | ||||
|         }; | ||||
|         NoColourImpl noColourImpl; | ||||
|         static const bool shouldUseColour = shouldUseColourForPlatform() && | ||||
|                                             !isDebuggerActive(); | ||||
|         static bool shouldUseColour() { | ||||
|             return shouldUseColourForPlatform() && !isDebuggerActive(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Colour::Colour( Code _colourCode ){ use( _colourCode ); } | ||||
|     Colour::~Colour(){ use( None ); } | ||||
|     void Colour::use( Code _colourCode ) { | ||||
|         impl->use( _colourCode ); | ||||
|         impl()->use( _colourCode ); | ||||
|     } | ||||
|  | ||||
|     Detail::IColourImpl* Colour::impl = shouldUseColour | ||||
|             ? static_cast<Detail::IColourImpl*>( &platformColourImpl ) | ||||
|             : static_cast<Detail::IColourImpl*>( &noColourImpl ); | ||||
|     Detail::IColourImpl* Colour::impl() { | ||||
|         return shouldUseColour() | ||||
|             ? platformColourInstance() | ||||
|             : NoColourImpl::instance(); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
|  | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include "catch_ptr.hpp" | ||||
|  | ||||
| @@ -32,6 +33,8 @@ namespace Catch { | ||||
|         Never | ||||
|     }; }; | ||||
|  | ||||
|     class TestCaseFilters; | ||||
|  | ||||
|     struct IConfig : IShared { | ||||
|  | ||||
|         virtual ~IConfig(); | ||||
| @@ -44,6 +47,7 @@ namespace Catch { | ||||
|         virtual bool warnAboutMissingAssertions() const = 0; | ||||
|         virtual int abortAfter() const = 0; | ||||
|         virtual ShowDurations::OrNot showDurations() const = 0; | ||||
|         virtual std::vector<TestCaseFilters> const& filters() const = 0; | ||||
|     }; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -23,11 +23,14 @@ namespace Catch { | ||||
|     }; | ||||
|  | ||||
|     class TestCase; | ||||
|     struct IConfig; | ||||
|  | ||||
|     struct ITestCaseRegistry { | ||||
|         virtual ~ITestCaseRegistry(); | ||||
|         virtual std::vector<TestCase> const& getAllTests() const = 0; | ||||
|         virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const = 0; | ||||
|         virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0; | ||||
|         virtual void getFilteredTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0; | ||||
|  | ||||
|     }; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -17,14 +17,6 @@ | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
|     inline bool matchesFilters( std::vector<TestCaseFilters> const& filters, TestCase const& testCase ) { | ||||
|         std::vector<TestCaseFilters>::const_iterator it = filters.begin(); | ||||
|         std::vector<TestCaseFilters>::const_iterator itEnd = filters.end(); | ||||
|         for(; it != itEnd; ++it ) | ||||
|             if( !it->shouldInclude( testCase ) ) | ||||
|                 return false; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     inline std::size_t listTests( Config const& config ) { | ||||
|         if( config.filters().empty() ) | ||||
| @@ -37,11 +29,11 @@ namespace Catch { | ||||
|         nameAttr.setInitialIndent( 2 ).setIndent( 4 ); | ||||
|         tagsAttr.setIndent( 6 ); | ||||
|  | ||||
|         std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); | ||||
|         for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end(); | ||||
|         std::vector<TestCase> matchedTestCases; | ||||
|         getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) | ||||
|             if( matchesFilters( config.filters(), *it ) ) { | ||||
|                 ++it ) { | ||||
|             matchedTests++; | ||||
|             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); | ||||
|             Colour::Code colour = testCaseInfo.isHidden | ||||
| @@ -63,11 +55,11 @@ namespace Catch { | ||||
|  | ||||
|     inline std::size_t listTestsNamesOnly( Config const& config ) { | ||||
|         std::size_t matchedTests = 0; | ||||
|         std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); | ||||
|         for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end(); | ||||
|         std::vector<TestCase> matchedTestCases; | ||||
|         getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) | ||||
|             if( matchesFilters( config.filters(), *it ) ) { | ||||
|                 ++it ) { | ||||
|             matchedTests++; | ||||
|             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); | ||||
|             std::cout << testCaseInfo.name << std::endl; | ||||
| @@ -83,12 +75,11 @@ namespace Catch { | ||||
|  | ||||
|         std::map<std::string, int> tagCounts; | ||||
|  | ||||
|         std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); | ||||
|         for( std::vector<TestCase>::const_iterator  it = allTests.begin(), | ||||
|                                                     itEnd = allTests.end(); | ||||
|         std::vector<TestCase> matchedTestCases; | ||||
|         getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) { | ||||
|             if( matchesFilters( config.filters(), *it ) ) { | ||||
|             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(), | ||||
|                                                         tagItEnd = it->getTestCaseInfo().tags.end(); | ||||
|                     tagIt != tagItEnd; | ||||
| @@ -101,7 +92,6 @@ namespace Catch { | ||||
|                     countIt->second++; | ||||
|             } | ||||
|         } | ||||
|         } | ||||
|  | ||||
|         for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(), | ||||
|                                                         countItEnd = tagCounts.end(); | ||||
|   | ||||
| @@ -88,23 +88,6 @@ namespace Catch { | ||||
|             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); | ||||
|         } | ||||
|  | ||||
|         Totals runMatching( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { | ||||
|  | ||||
|             std::vector<TestCase> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec ); | ||||
|  | ||||
|             Totals totals; | ||||
|  | ||||
|             testGroupStarting( testSpec, groupIndex, groupsCount ); | ||||
|  | ||||
|             std::vector<TestCase>::const_iterator it = matchingTests.begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = matchingTests.end(); | ||||
|             for(; it != itEnd; ++it ) | ||||
|                 totals += runTest( *it ); | ||||
|  | ||||
|             testGroupEnded( testSpec, totals, groupIndex, groupsCount ); | ||||
|             return totals; | ||||
|         } | ||||
|  | ||||
|         Totals runTest( TestCase const& testCase ) { | ||||
|             Totals prevTotals = m_totals; | ||||
|  | ||||
|   | ||||
| @@ -40,6 +40,7 @@ namespace Catch { | ||||
|         std::string tagsAsString; | ||||
|         SourceLineInfo lineInfo; | ||||
|         bool isHidden; | ||||
|         bool throws; | ||||
|     }; | ||||
|  | ||||
|     class TestCase : protected TestCaseInfo { | ||||
| @@ -55,6 +56,7 @@ namespace Catch { | ||||
|         TestCaseInfo const& getTestCaseInfo() const; | ||||
|  | ||||
|         bool isHidden() const; | ||||
|         bool throws() const; | ||||
|         bool hasTag( std::string const& tag ) const; | ||||
|         bool matchesTags( std::string const& tagPattern ) const; | ||||
|         std::set<std::string> const& getTags() const; | ||||
|   | ||||
| @@ -15,6 +15,16 @@ | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     inline bool isSpecialTag( std::string const& tag ) { | ||||
|         return  tag == "." || | ||||
|                 tag == "hide" || | ||||
|                 tag == "!hide" || | ||||
|                 tag == "!throws"; | ||||
|     } | ||||
|     inline bool isReservedTag( std::string const& tag ) { | ||||
|         return !isSpecialTag( tag ) && tag.size() > 0 && !isalnum( tag[0] ); | ||||
|     } | ||||
|  | ||||
|     TestCase makeTestCase(  ITestCase* _testCase, | ||||
|                             std::string const& _className, | ||||
|                             std::string const& _name, | ||||
| @@ -25,6 +35,23 @@ namespace Catch { | ||||
|         bool isHidden( startsWith( _name, "./" ) ); // Legacy support | ||||
|         std::set<std::string> tags; | ||||
|         TagExtracter( tags ).parse( desc ); | ||||
|         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) | ||||
|             if( isReservedTag( *it ) ) { | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::Red ); | ||||
|                     std::cerr | ||||
|                         << "Tag name [" << *it << "] not allowed.\n" | ||||
|                         << "Tag names starting with non alpha-numeric characters are reserved\n"; | ||||
|                 } | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::FileName ); | ||||
|                     std::cerr << _lineInfo << std::endl; | ||||
|                 } | ||||
|                 exit(1); | ||||
|             } | ||||
|  | ||||
|         if( tags.find( "hide" ) != tags.end() || tags.find( "." ) != tags.end() ) | ||||
|             isHidden = true; | ||||
|  | ||||
| @@ -47,11 +74,15 @@ namespace Catch { | ||||
|         description( _description ), | ||||
|         tags( _tags ), | ||||
|         lineInfo( _lineInfo ), | ||||
|         isHidden( _isHidden ) | ||||
|         isHidden( _isHidden ), | ||||
|         throws( false ) | ||||
|     { | ||||
|         std::ostringstream oss; | ||||
|         for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) | ||||
|         for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) { | ||||
|             oss << "[" << *it << "]"; | ||||
|             if( *it == "!throws" ) | ||||
|                 throws = true; | ||||
|         } | ||||
|         tagsAsString = oss.str(); | ||||
|     } | ||||
|  | ||||
| @@ -62,7 +93,8 @@ namespace Catch { | ||||
|         tags( other.tags ), | ||||
|         tagsAsString( other.tagsAsString ), | ||||
|         lineInfo( other.lineInfo ), | ||||
|         isHidden( other.isHidden ) | ||||
|         isHidden( other.isHidden ), | ||||
|         throws( other.throws ) | ||||
|     {} | ||||
|  | ||||
|     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} | ||||
| @@ -85,6 +117,9 @@ namespace Catch { | ||||
|     bool TestCase::isHidden() const { | ||||
|         return TestCaseInfo::isHidden; | ||||
|     } | ||||
|     bool TestCase::throws() const { | ||||
|         return TestCaseInfo::throws; | ||||
|     } | ||||
|  | ||||
|     bool TestCase::hasTag( std::string const& tag ) const { | ||||
|         return tags.find( toLower( tag ) ) != tags.end(); | ||||
|   | ||||
| @@ -41,9 +41,12 @@ namespace Catch { | ||||
|             } | ||||
|             else { | ||||
|                 TestCase const& prev = *m_functions.find( testCase ); | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::Red ); | ||||
|                     std::cerr   << "error: TEST_CASE( \"" << name << "\" ) already defined.\n" | ||||
|                                 << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n" | ||||
|                                 << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl; | ||||
|                 } | ||||
|                 exit(1); | ||||
|             } | ||||
|         } | ||||
| @@ -56,32 +59,24 @@ namespace Catch { | ||||
|             return m_nonHiddenFunctions; | ||||
|         } | ||||
|  | ||||
|         // !TBD deprecated | ||||
|         virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const { | ||||
|             std::vector<TestCase> matchingTests; | ||||
|             getMatchingTestCases( rawTestSpec, matchingTests ); | ||||
|             return matchingTests; | ||||
|         virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const { | ||||
|             for( std::vector<TestCase>::const_iterator  it = m_functionsInOrder.begin(), | ||||
|                                                         itEnd = m_functionsInOrder.end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) { | ||||
|                 if( filters.shouldInclude( *it ) && ( config.allowThrows() || !it->throws() ) ) | ||||
|                     matchingTestCases.push_back( *it ); | ||||
|             } | ||||
|         } | ||||
|         virtual void getFilteredTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) const { | ||||
|             if( config.filters().empty() ) | ||||
|                 return getFilteredTests( TestCaseFilters( "empty" ), config, matchingTestCases ); | ||||
|  | ||||
|         // !TBD deprecated | ||||
|         virtual void getMatchingTestCases( std::string const& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const { | ||||
|             TestCaseFilter filter( rawTestSpec ); | ||||
|  | ||||
|             std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end(); | ||||
|             for(; it != itEnd; ++it ) { | ||||
|                 if( filter.shouldInclude( *it ) ) { | ||||
|                     matchingTestsOut.push_back( *it ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         virtual void getMatchingTestCases( TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut ) const { | ||||
|             std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end(); | ||||
|             // !TBD: replace with algorithm | ||||
|             for(; it != itEnd; ++it ) | ||||
|                 if( filters.shouldInclude( *it ) ) | ||||
|                     matchingTestsOut.push_back( *it ); | ||||
|             for( std::vector<TestCaseFilters>::const_iterator   it = config.filters().begin(), | ||||
|                                                                 itEnd = config.filters().end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) | ||||
|                 getFilteredTests( *it, config, matchingTestCases ); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| namespace Catch { | ||||
|  | ||||
|     // These numbers are maintained by a script | ||||
|     Version libraryVersion( 1, 0, 35, "master" ); | ||||
|     Version libraryVersion( 1, 0, 36, "master" ); | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED | ||||
|   | ||||
| @@ -774,5 +774,5 @@ with expansion: | ||||
|   "first" == "second" | ||||
|  | ||||
| =============================================================================== | ||||
| 124 test cases - 38 failed (660 assertions - 93 failed) | ||||
| 125 test cases - 38 failed (660 assertions - 93 failed) | ||||
|  | ||||
|   | ||||
| @@ -3650,6 +3650,15 @@ MiscTests.cpp:<line number>: FAILED: | ||||
| explicitly with message: | ||||
|   to infinity and beyond | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| not allowed | ||||
| ------------------------------------------------------------------------------- | ||||
| MiscTests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
|  | ||||
| No assertions in test case 'not allowed' | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Process can be configured on command line | ||||
|   default - no arguments | ||||
| @@ -6982,5 +6991,5 @@ with expansion: | ||||
|   true | ||||
|  | ||||
| =============================================================================== | ||||
| 124 test cases - 53 failed (679 assertions - 112 failed) | ||||
| 125 test cases - 54 failed (680 assertions - 113 failed) | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <testsuites> | ||||
|   <testsuite name="~_" errors="12" failures="100" tests="679" hostname="tbd" time="{duration}" timestamp="tbd"> | ||||
|   <testsuite name="~_" errors="12" failures="101" tests="680" hostname="tbd" time="{duration}" timestamp="tbd"> | ||||
|     <testcase classname="global" name="Some simple comparisons between doubles" time="{duration}"/> | ||||
|     <testcase classname="global" name="Approximate comparisons with different epsilons" time="{duration}"/> | ||||
|     <testcase classname="global" name="Approximate comparisons with floats" time="{duration}"/> | ||||
|   | ||||
| @@ -3723,6 +3723,9 @@ | ||||
|       </Failure> | ||||
|       <OverallResult success="false"/> | ||||
|     </TestCase> | ||||
|     <TestCase name="not allowed"> | ||||
|       <OverallResult success="true"/> | ||||
|     </TestCase> | ||||
|     <TestCase name="Process can be configured on command line"> | ||||
|       <Section name="default - no arguments"> | ||||
|         <Expression success="true" filename="/Users/philnash/Dev/OSS/Catch/projects/SelfTest/TestMain.cpp" > | ||||
| @@ -7242,7 +7245,7 @@ there" | ||||
|       </Section> | ||||
|       <OverallResult success="true"/> | ||||
|     </TestCase> | ||||
|     <OverallResults successes="567" failures="112"/> | ||||
|     <OverallResults successes="567" failures="113"/> | ||||
|   </Group> | ||||
|   <OverallResults successes="567" failures="112"/> | ||||
|   <OverallResults successes="567" failures="113"/> | ||||
| </Catch> | ||||
|   | ||||
| @@ -333,3 +333,9 @@ TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") | ||||
|  | ||||
|     FAIL("to infinity and beyond"); | ||||
| } | ||||
|  | ||||
| TEST_CASE("not allowed", "[!throws]") | ||||
| { | ||||
|     // This test case should not be included if you run with -e on the command line | ||||
|     SUCCEED(); | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
|  *  CATCH v1.0 build 35 (master branch) | ||||
|  *  Generated: 2014-04-12 19:20:39.856403 | ||||
|  *  CATCH v1.0 build 36 (master branch) | ||||
|  *  Generated: 2014-04-15 18:42:33.686099 | ||||
|  *  ---------------------------------------------------------- | ||||
|  *  This file has been merged from multiple headers. Please don't edit it directly | ||||
|  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. | ||||
| @@ -420,11 +420,14 @@ namespace Catch { | ||||
|     }; | ||||
|  | ||||
|     class TestCase; | ||||
|     struct IConfig; | ||||
|  | ||||
|     struct ITestCaseRegistry { | ||||
|         virtual ~ITestCaseRegistry(); | ||||
|         virtual std::vector<TestCase> const& getAllTests() const = 0; | ||||
|         virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const = 0; | ||||
|         virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0; | ||||
|         virtual void getFilteredTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0; | ||||
|  | ||||
|     }; | ||||
| } | ||||
|  | ||||
| @@ -1497,6 +1500,7 @@ namespace Catch { | ||||
|  | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -1517,6 +1521,8 @@ namespace Catch { | ||||
|         Never | ||||
|     }; }; | ||||
|  | ||||
|     class TestCaseFilters; | ||||
|  | ||||
|     struct IConfig : IShared { | ||||
|  | ||||
|         virtual ~IConfig(); | ||||
| @@ -1529,6 +1535,7 @@ namespace Catch { | ||||
|         virtual bool warnAboutMissingAssertions() const = 0; | ||||
|         virtual int abortAfter() const = 0; | ||||
|         virtual ShowDurations::OrNot showDurations() const = 0; | ||||
|         virtual std::vector<TestCaseFilters> const& filters() const = 0; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| @@ -2411,6 +2418,7 @@ namespace Catch { | ||||
|         std::string tagsAsString; | ||||
|         SourceLineInfo lineInfo; | ||||
|         bool isHidden; | ||||
|         bool throws; | ||||
|     }; | ||||
|  | ||||
|     class TestCase : protected TestCaseInfo { | ||||
| @@ -2426,6 +2434,7 @@ namespace Catch { | ||||
|         TestCaseInfo const& getTestCaseInfo() const; | ||||
|  | ||||
|         bool isHidden() const; | ||||
|         bool throws() const; | ||||
|         bool hasTag( std::string const& tag ) const; | ||||
|         bool matchesTags( std::string const& tagPattern ) const; | ||||
|         std::set<std::string> const& getTags() const; | ||||
| @@ -4221,7 +4230,7 @@ namespace Catch { | ||||
|         static void use( Code _colourCode ); | ||||
|  | ||||
|     private: | ||||
|         static Detail::IColourImpl* impl; | ||||
|         static Detail::IColourImpl* impl(); | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
| @@ -4505,14 +4514,6 @@ namespace Catch | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
|     inline bool matchesFilters( std::vector<TestCaseFilters> const& filters, TestCase const& testCase ) { | ||||
|         std::vector<TestCaseFilters>::const_iterator it = filters.begin(); | ||||
|         std::vector<TestCaseFilters>::const_iterator itEnd = filters.end(); | ||||
|         for(; it != itEnd; ++it ) | ||||
|             if( !it->shouldInclude( testCase ) ) | ||||
|                 return false; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     inline std::size_t listTests( Config const& config ) { | ||||
|         if( config.filters().empty() ) | ||||
| @@ -4525,11 +4526,11 @@ namespace Catch { | ||||
|         nameAttr.setInitialIndent( 2 ).setIndent( 4 ); | ||||
|         tagsAttr.setIndent( 6 ); | ||||
|  | ||||
|         std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); | ||||
|         for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end(); | ||||
|         std::vector<TestCase> matchedTestCases; | ||||
|         getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) | ||||
|             if( matchesFilters( config.filters(), *it ) ) { | ||||
|                 ++it ) { | ||||
|             matchedTests++; | ||||
|             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); | ||||
|             Colour::Code colour = testCaseInfo.isHidden | ||||
| @@ -4551,11 +4552,11 @@ namespace Catch { | ||||
|  | ||||
|     inline std::size_t listTestsNamesOnly( Config const& config ) { | ||||
|         std::size_t matchedTests = 0; | ||||
|         std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); | ||||
|         for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end(); | ||||
|         std::vector<TestCase> matchedTestCases; | ||||
|         getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) | ||||
|             if( matchesFilters( config.filters(), *it ) ) { | ||||
|                 ++it ) { | ||||
|             matchedTests++; | ||||
|             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); | ||||
|             std::cout << testCaseInfo.name << std::endl; | ||||
| @@ -4571,12 +4572,11 @@ namespace Catch { | ||||
|  | ||||
|         std::map<std::string, int> tagCounts; | ||||
|  | ||||
|         std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); | ||||
|         for( std::vector<TestCase>::const_iterator  it = allTests.begin(), | ||||
|                                                     itEnd = allTests.end(); | ||||
|         std::vector<TestCase> matchedTestCases; | ||||
|         getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) { | ||||
|             if( matchesFilters( config.filters(), *it ) ) { | ||||
|             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(), | ||||
|                                                         tagItEnd = it->getTestCaseInfo().tags.end(); | ||||
|                     tagIt != tagItEnd; | ||||
| @@ -4589,7 +4589,6 @@ namespace Catch { | ||||
|                     countIt->second++; | ||||
|             } | ||||
|         } | ||||
|         } | ||||
|  | ||||
|         for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(), | ||||
|                                                         countItEnd = tagCounts.end(); | ||||
| @@ -4856,23 +4855,6 @@ namespace Catch { | ||||
|             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); | ||||
|         } | ||||
|  | ||||
|         Totals runMatching( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { | ||||
|  | ||||
|             std::vector<TestCase> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec ); | ||||
|  | ||||
|             Totals totals; | ||||
|  | ||||
|             testGroupStarting( testSpec, groupIndex, groupsCount ); | ||||
|  | ||||
|             std::vector<TestCase>::const_iterator it = matchingTests.begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = matchingTests.end(); | ||||
|             for(; it != itEnd; ++it ) | ||||
|                 totals += runTest( *it ); | ||||
|  | ||||
|             testGroupEnded( testSpec, totals, groupIndex, groupsCount ); | ||||
|             return totals; | ||||
|         } | ||||
|  | ||||
|         Totals runTest( TestCase const& testCase ) { | ||||
|             Totals prevTotals = m_totals; | ||||
|  | ||||
| @@ -5165,14 +5147,16 @@ namespace Catch { | ||||
|             } | ||||
|             return totals; | ||||
|         } | ||||
|  | ||||
|         Totals runTestsForGroup( RunContext& context, const TestCaseFilters& filterGroup ) { | ||||
|         Totals runTestsForGroup( RunContext& context, TestCaseFilters const& filterGroup ) { | ||||
|             Totals totals; | ||||
|             std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end(); | ||||
|  | ||||
|             std::vector<TestCase> testCases; | ||||
|             getRegistryHub().getTestCaseRegistry().getFilteredTests( filterGroup, *m_config, testCases ); | ||||
|  | ||||
|             int testsRunForGroup = 0; | ||||
|             for(; it != itEnd; ++it ) { | ||||
|                 if( filterGroup.shouldInclude( *it ) ) { | ||||
|             for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) { | ||||
|                 testsRunForGroup++; | ||||
|                 if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) { | ||||
|  | ||||
| @@ -5183,11 +5167,9 @@ namespace Catch { | ||||
|                     m_testsAlreadyRun.insert( *it ); | ||||
|                 } | ||||
|             } | ||||
|             } | ||||
|             if( testsRunForGroup == 0 && !filterGroup.getName().empty() ) | ||||
|                 m_reporter->noMatchingTestCases( filterGroup.getName() ); | ||||
|             return totals; | ||||
|  | ||||
|         } | ||||
|  | ||||
|     private: | ||||
| @@ -5370,9 +5352,12 @@ namespace Catch { | ||||
|             } | ||||
|             else { | ||||
|                 TestCase const& prev = *m_functions.find( testCase ); | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::Red ); | ||||
|                     std::cerr   << "error: TEST_CASE( \"" << name << "\" ) already defined.\n" | ||||
|                                 << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n" | ||||
|                                 << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl; | ||||
|                 } | ||||
|                 exit(1); | ||||
|             } | ||||
|         } | ||||
| @@ -5385,32 +5370,24 @@ namespace Catch { | ||||
|             return m_nonHiddenFunctions; | ||||
|         } | ||||
|  | ||||
|         // !TBD deprecated | ||||
|         virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const { | ||||
|             std::vector<TestCase> matchingTests; | ||||
|             getMatchingTestCases( rawTestSpec, matchingTests ); | ||||
|             return matchingTests; | ||||
|         virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const { | ||||
|             for( std::vector<TestCase>::const_iterator  it = m_functionsInOrder.begin(), | ||||
|                                                         itEnd = m_functionsInOrder.end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) { | ||||
|                 if( filters.shouldInclude( *it ) && ( config.allowThrows() || !it->throws() ) ) | ||||
|                     matchingTestCases.push_back( *it ); | ||||
|             } | ||||
|         } | ||||
|         virtual void getFilteredTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) const { | ||||
|             if( config.filters().empty() ) | ||||
|                 return getFilteredTests( TestCaseFilters( "empty" ), config, matchingTestCases ); | ||||
|  | ||||
|         // !TBD deprecated | ||||
|         virtual void getMatchingTestCases( std::string const& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const { | ||||
|             TestCaseFilter filter( rawTestSpec ); | ||||
|  | ||||
|             std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end(); | ||||
|             for(; it != itEnd; ++it ) { | ||||
|                 if( filter.shouldInclude( *it ) ) { | ||||
|                     matchingTestsOut.push_back( *it ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         virtual void getMatchingTestCases( TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut ) const { | ||||
|             std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(); | ||||
|             std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end(); | ||||
|             // !TBD: replace with algorithm | ||||
|             for(; it != itEnd; ++it ) | ||||
|                 if( filters.shouldInclude( *it ) ) | ||||
|                     matchingTestsOut.push_back( *it ); | ||||
|             for( std::vector<TestCaseFilters>::const_iterator   it = config.filters().begin(), | ||||
|                                                                 itEnd = config.filters().end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) | ||||
|                 getFilteredTests( *it, config, matchingTestCases ); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
| @@ -5909,7 +5886,10 @@ namespace { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     Win32ColourImpl platformColourImpl; | ||||
|     static Detail::IColourImpl* platformColourInstance() { | ||||
|         static Win32ColourImpl s_instance; | ||||
|         return &s_instance; | ||||
|     } | ||||
|  | ||||
| } // end anon namespace | ||||
| } // end namespace Catch | ||||
| @@ -5956,7 +5936,10 @@ namespace { | ||||
|         return isatty(STDOUT_FILENO); | ||||
|     } | ||||
|  | ||||
|     PosixColourImpl platformColourImpl; | ||||
|     static Detail::IColourImpl* platformColourInstance() { | ||||
|         static PosixColourImpl s_instance; | ||||
|         return &s_instance; | ||||
|     } | ||||
|  | ||||
| } // end anon namespace | ||||
| } // end namespace Catch | ||||
| @@ -5968,21 +5951,28 @@ namespace Catch { | ||||
|     namespace { | ||||
|         struct NoColourImpl : Detail::IColourImpl { | ||||
|             void use( Colour::Code ) {} | ||||
|  | ||||
|             static IColourImpl* instance() { | ||||
|                 static NoColourImpl s_instance; | ||||
|                 return &s_instance; | ||||
|             } | ||||
|         }; | ||||
|         NoColourImpl noColourImpl; | ||||
|         static const bool shouldUseColour = shouldUseColourForPlatform() && | ||||
|                                             !isDebuggerActive(); | ||||
|         static bool shouldUseColour() { | ||||
|             return shouldUseColourForPlatform() && !isDebuggerActive(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Colour::Colour( Code _colourCode ){ use( _colourCode ); } | ||||
|     Colour::~Colour(){ use( None ); } | ||||
|     void Colour::use( Code _colourCode ) { | ||||
|         impl->use( _colourCode ); | ||||
|         impl()->use( _colourCode ); | ||||
|     } | ||||
|  | ||||
|     Detail::IColourImpl* Colour::impl = shouldUseColour | ||||
|             ? static_cast<Detail::IColourImpl*>( &platformColourImpl ) | ||||
|             : static_cast<Detail::IColourImpl*>( &noColourImpl ); | ||||
|     Detail::IColourImpl* Colour::impl() { | ||||
|         return shouldUseColour() | ||||
|             ? platformColourInstance() | ||||
|             : NoColourImpl::instance(); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| @@ -6233,6 +6223,16 @@ namespace Catch { | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     inline bool isSpecialTag( std::string const& tag ) { | ||||
|         return  tag == "." || | ||||
|                 tag == "hide" || | ||||
|                 tag == "!hide" || | ||||
|                 tag == "!throws"; | ||||
|     } | ||||
|     inline bool isReservedTag( std::string const& tag ) { | ||||
|         return !isSpecialTag( tag ) && tag.size() > 0 && !isalnum( tag[0] ); | ||||
|     } | ||||
|  | ||||
|     TestCase makeTestCase(  ITestCase* _testCase, | ||||
|                             std::string const& _className, | ||||
|                             std::string const& _name, | ||||
| @@ -6243,6 +6243,23 @@ namespace Catch { | ||||
|         bool isHidden( startsWith( _name, "./" ) ); // Legacy support | ||||
|         std::set<std::string> tags; | ||||
|         TagExtracter( tags ).parse( desc ); | ||||
|         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) | ||||
|             if( isReservedTag( *it ) ) { | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::Red ); | ||||
|                     std::cerr | ||||
|                         << "Tag name [" << *it << "] not allowed.\n" | ||||
|                         << "Tag names starting with non alpha-numeric characters are reserved\n"; | ||||
|                 } | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::FileName ); | ||||
|                     std::cerr << _lineInfo << std::endl; | ||||
|                 } | ||||
|                 exit(1); | ||||
|             } | ||||
|  | ||||
|         if( tags.find( "hide" ) != tags.end() || tags.find( "." ) != tags.end() ) | ||||
|             isHidden = true; | ||||
|  | ||||
| @@ -6265,11 +6282,15 @@ namespace Catch { | ||||
|         description( _description ), | ||||
|         tags( _tags ), | ||||
|         lineInfo( _lineInfo ), | ||||
|         isHidden( _isHidden ) | ||||
|         isHidden( _isHidden ), | ||||
|         throws( false ) | ||||
|     { | ||||
|         std::ostringstream oss; | ||||
|         for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) | ||||
|         for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) { | ||||
|             oss << "[" << *it << "]"; | ||||
|             if( *it == "!throws" ) | ||||
|                 throws = true; | ||||
|         } | ||||
|         tagsAsString = oss.str(); | ||||
|     } | ||||
|  | ||||
| @@ -6280,7 +6301,8 @@ namespace Catch { | ||||
|         tags( other.tags ), | ||||
|         tagsAsString( other.tagsAsString ), | ||||
|         lineInfo( other.lineInfo ), | ||||
|         isHidden( other.isHidden ) | ||||
|         isHidden( other.isHidden ), | ||||
|         throws( other.throws ) | ||||
|     {} | ||||
|  | ||||
|     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} | ||||
| @@ -6303,6 +6325,9 @@ namespace Catch { | ||||
|     bool TestCase::isHidden() const { | ||||
|         return TestCaseInfo::isHidden; | ||||
|     } | ||||
|     bool TestCase::throws() const { | ||||
|         return TestCaseInfo::throws; | ||||
|     } | ||||
|  | ||||
|     bool TestCase::hasTag( std::string const& tag ) const { | ||||
|         return tags.find( toLower( tag ) ) != tags.end(); | ||||
| @@ -6598,7 +6623,7 @@ namespace Catch { | ||||
| namespace Catch { | ||||
|  | ||||
|     // These numbers are maintained by a script | ||||
|     Version libraryVersion( 1, 0, 35, "master" ); | ||||
|     Version libraryVersion( 1, 0, 36, "master" ); | ||||
| } | ||||
|  | ||||
| // #included from: catch_message.hpp | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash