diff options
| author | Matt Wozniski | 2012-09-26 21:42:44 -0400 |
|---|---|---|
| committer | Matt Wozniski | 2012-09-26 21:42:44 -0400 |
| commit | 07e20aa706abe28d544ae2f8d0f1ba2f855e1e6d (patch) | |
| tree | 8538694d451118cbc7f491977f70d1a5319f7bd6 | |
| parent | f29c898443d65cc3fe2f040e700c64bba907288e (diff) | |
| parent | 67ec8709eae23dfb4fe30f789fd788d5a9c77ea8 (diff) | |
| download | catch3-07e20aa706abe28d544ae2f8d0f1ba2f855e1e6d.tar.gz | |
Merge remote-tracking branch 'phil' into include-guard-fixes
Conflicts:
single_include/catch.hpp
| -rw-r--r-- | include/catch_runner.hpp | 14 | ||||
| -rw-r--r-- | include/internal/catch_capture.hpp | 4 | ||||
| -rw-r--r-- | include/internal/catch_commandline.hpp | 51 | ||||
| -rw-r--r-- | include/internal/catch_config.hpp | 17 | ||||
| -rw-r--r-- | include/internal/catch_context.h | 3 | ||||
| -rw-r--r-- | include/internal/catch_context_impl.hpp | 8 | ||||
| -rw-r--r-- | include/internal/catch_impl.hpp | 4 | ||||
| -rw-r--r-- | include/internal/catch_interfaces_reporter.h | 11 | ||||
| -rw-r--r-- | include/internal/catch_runner_impl.hpp | 16 | ||||
| -rw-r--r-- | include/internal/catch_stream.hpp | 24 | ||||
| -rw-r--r-- | include/internal/catch_tags.hpp | 195 | ||||
| -rw-r--r-- | include/internal/catch_test_case_info.h | 3 | ||||
| -rw-r--r-- | include/internal/catch_test_case_info.hpp | 44 | ||||
| -rw-r--r-- | include/internal/catch_test_spec.h | 21 | ||||
| -rw-r--r-- | projects/SelfTest/MiscTests.cpp | 8 | ||||
| -rw-r--r-- | projects/SelfTest/SurrogateCpps/catch_tags.cpp | 1 | ||||
| -rw-r--r-- | projects/SelfTest/TestMain.cpp | 54 | ||||
| -rw-r--r-- | projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj | 14 | ||||
| -rw-r--r-- | single_include/catch.hpp | 508 |
19 files changed, 800 insertions, 200 deletions
diff --git a/include/catch_runner.hpp b/include/catch_runner.hpp index c849ccb2..8f18267a 100644 --- a/include/catch_runner.hpp +++ b/include/catch_runner.hpp @@ -26,7 +26,7 @@ namespace Catch { : m_configWrapper( configWrapper ), m_config( configWrapper.data() ) { - resolveStream(); + openStream(); makeReporter(); } @@ -78,13 +78,10 @@ namespace Catch { } private: - void resolveStream() { - if( !m_config.stream.empty() ) { - if( m_config.stream[0] == '%' ) - m_configWrapper.useStream( m_config.stream.substr( 1 ) ); - else - m_configWrapper.setFilename( m_config.stream ); - } + void openStream() { + if( !m_config.stream.empty() ) + m_configWrapper.useStream( m_config.stream ); + // Open output file, if specified if( !m_config.outputFilename.empty() ) { m_ofs.open( m_config.outputFilename.c_str() ); @@ -130,6 +127,7 @@ namespace Catch { // Handle list request if( config.listSpec != List::None ) { List( config ); + Catch::cleanUp(); return 0; } diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp index c4f28757..379cc24c 100644 --- a/include/internal/catch_capture.hpp +++ b/include/internal/catch_capture.hpp @@ -35,8 +35,8 @@ public: return *this; } - std::string getInfo () const { - return m_oss.str(); + ResultInfo getInfo () const { + return ResultInfo( "", ResultWas::Info, false, SourceLineInfo(), "SCOPED_INFO", m_oss.str().c_str() ); } private: diff --git a/include/internal/catch_commandline.hpp b/include/internal/catch_commandline.hpp index 38c60855..f03ae3c8 100644 --- a/include/internal/catch_commandline.hpp +++ b/include/internal/catch_commandline.hpp @@ -188,10 +188,10 @@ namespace Catch { m_optionNames.push_back( "--help" ); } virtual std::string argsSynopsis() const { - return "[<option for help on>]"; + return "[<option for help on> ...]"; } virtual std::string optionSummary() const { - return "Shows this usage summary, or help on a specific option, if supplied"; + return "Shows this usage summary, or help on a specific option, or options, if supplied"; } virtual std::string optionDescription() const { return ""; @@ -235,7 +235,7 @@ namespace Catch { "\n" "If spec is prefixed with exclude: or the ~ character then the pattern matches an exclusion. " "This means that tests matching the pattern are excluded from the set - even if a prior " - "inclusion spec included them. Subsequent inclusion specs will take precendence, however. " + "inclusion spec included them. Subsequent inclusion specs will take precedence, however. " "Inclusions and exclusions are evaluated in left-to-right order.\n" "\n" "Examples:\n" @@ -249,7 +249,7 @@ namespace Catch { " -t a/* ~a/b/* a/b/c \tMatches all tests that start with 'a/', except those " "that start with 'a/b/', except 'a/b/c', which is included"; } - + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { std::string groupName; for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { @@ -264,6 +264,42 @@ namespace Catch { } }; + class TagOptionParser : public OptionParser { + public: + TagOptionParser() : OptionParser( 1, -1 ) { + m_optionNames.push_back( "-g" ); + m_optionNames.push_back( "--tag" ); + } + virtual std::string argsSynopsis() const { + return "<tagspec> [,<tagspec>...]"; + } + virtual std::string optionSummary() const { + return "Matches test cases against tags or tag patterns"; + } + + // Lines are split at the nearest prior space char to the 80 char column. + // Tab chars are removed from the output but their positions are used to align + // subsequently wrapped lines + virtual std::string optionDescription() const { + return + "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + std::string groupName; + for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { + if( i != 0 ) + groupName += " "; + groupName += cmd[i]; + } + TestCaseFilters filters( groupName ); + for( std::size_t i = 0; i < cmd.argsCount(); ++i ) + filters.addTags( cmd[i] ); + config.filters.push_back( filters ); + } + }; + + class ListOptionParser : public OptionParser { public: ListOptionParser() : OptionParser( 0, 2 ) { @@ -369,9 +405,9 @@ namespace Catch { virtual std::string optionDescription() const { return "Use this option to send all output to a file or a stream. By default output is " - "sent to stdout (note that uses ofstdout and stderr from within test cases are " + "sent to stdout (note that uses of stdout and stderr from within test cases are " "redirected and included in the report - so even stderr will effectively end up " - "on stdout). If the name begins with % it is interpretted as a stream. " + "on stdout). If the name begins with % it is interpreted as a stream. " "Otherwise it is treated as a filename.\n" "\n" "Examples are:\n" @@ -407,7 +443,7 @@ namespace Catch { return "Usually you only want to see reporting for failed tests. Sometimes it's useful " "to see all the output (especially when you don't trust that that test you just " - "added worked first time!). To see successul, as well as failing, test results " + "added worked first time!). To see successful, as well as failing, test results " "just pass this option."; } virtual void parseIntoConfig( const Command&, ConfigData& config ) { @@ -586,6 +622,7 @@ namespace Catch { AllOptions() { add<Options::TestCaseOptionParser>(); // Keep this one first + add<Options::TagOptionParser>(); add<Options::ListOptionParser>(); add<Options::ReporterOptionParser>(); add<Options::OutputOptionParser>(); diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index 9eb231c2..72059f1f 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -11,6 +11,7 @@ #include "catch_test_spec.h" #include "catch_context.h" #include "catch_interfaces_config.h" +#include "catch_stream.hpp" #include <memory> #include <vector> @@ -79,19 +80,17 @@ namespace Catch { public: Config() - : m_streambuf( NULL ), - m_os( std::cout.rdbuf() ) + : m_os( std::cout.rdbuf() ) {} Config( const ConfigData& data ) : m_data( data ), - m_streambuf( NULL ), m_os( std::cout.rdbuf() ) {} virtual ~Config() { m_os.rdbuf( std::cout.rdbuf() ); - delete m_streambuf; + m_stream.release(); } void setFilename( const std::string& filename ) { @@ -131,10 +130,10 @@ namespace Catch { } void useStream( const std::string& streamName ) { - std::streambuf* newBuf = createStreamBuf( streamName ); - setStreamBuf( newBuf ); - delete m_streambuf; - m_streambuf = newBuf; + Stream stream = createStream( streamName ); + setStreamBuf( stream.streamBuf ); + m_stream.release(); + m_stream = stream; } void addTestSpec( const std::string& testSpec ) { @@ -166,7 +165,7 @@ namespace Catch { ConfigData m_data; // !TBD Move these out of here - std::streambuf* m_streambuf; + Stream m_stream; mutable std::ostream m_os; }; diff --git a/include/internal/catch_context.h b/include/internal/catch_context.h index 7ddd1f53..62b867ef 100644 --- a/include/internal/catch_context.h +++ b/include/internal/catch_context.h @@ -17,6 +17,7 @@ namespace Catch { class TestCaseInfo; + class Stream; struct IResultCapture; struct IRunner; struct IGeneratorsForTest; @@ -49,7 +50,7 @@ namespace Catch { IContext& getCurrentContext(); IMutableContext& getCurrentMutableContext(); void cleanUpContext(); - std::streambuf* createStreamBuf( const std::string& streamName ); + Stream createStream( const std::string& streamName ); } diff --git a/include/internal/catch_context_impl.hpp b/include/internal/catch_context_impl.hpp index 4efbfaa7..e9695725 100644 --- a/include/internal/catch_context_impl.hpp +++ b/include/internal/catch_context_impl.hpp @@ -95,10 +95,10 @@ namespace Catch { return getCurrentMutableContext(); } - std::streambuf* createStreamBuf( const std::string& streamName ) { - if( streamName == "stdout" ) return std::cout.rdbuf(); - if( streamName == "stderr" ) return std::cerr.rdbuf(); - if( streamName == "debug" ) return new StreamBufImpl<OutputDebugWriter>; + Stream createStream( const std::string& streamName ) { + if( streamName == "stdout" ) return Stream( std::cout.rdbuf(), false ); + if( streamName == "stderr" ) return Stream( std::cerr.rdbuf(), false ); + if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true ); throw std::domain_error( "Unknown stream: " + streamName ); } diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp index 15f74f99..93650761 100644 --- a/include/internal/catch_impl.hpp +++ b/include/internal/catch_impl.hpp @@ -25,6 +25,7 @@ #include "catch_resultinfo.hpp" #include "catch_resultinfo_builder.hpp" #include "catch_test_case_info.hpp" +#include "catch_tags.hpp" #include "../reporters/catch_reporter_basic.hpp" #include "../reporters/catch_reporter_xml.hpp" @@ -55,6 +56,9 @@ namespace Catch { FreeFunctionTestCase::~FreeFunctionTestCase() {} IGeneratorInfo::~IGeneratorInfo() {} IGeneratorsForTest::~IGeneratorsForTest() {} + TagParser::~TagParser() {} + TagExtracter::~TagExtracter() {} + TagExpressionParser::~TagExpressionParser() {} void Config::dummy() {} diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index bc6d586c..2fb5cc2a 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -31,10 +31,21 @@ namespace Catch fullConfig( _fullConfig ) {} + ReporterConfig( const ReporterConfig& other ) + : name( other.name ), + stream( other.stream ), + includeSuccessfulResults( other.includeSuccessfulResults ), + fullConfig( other.fullConfig ) + {} + + std::string name; std::ostream& stream; bool includeSuccessfulResults; ConfigData fullConfig; + + private: + void operator=(const ReporterConfig&); }; class TestCaseInfo; diff --git a/include/internal/catch_runner_impl.hpp b/include/internal/catch_runner_impl.hpp index ef5ec74f..c144414d 100644 --- a/include/internal/catch_runner_impl.hpp +++ b/include/internal/catch_runner_impl.hpp @@ -156,10 +156,18 @@ namespace Catch { else if( !result.ok() ) { m_totals.assertions.failed++; - std::vector<ResultInfo>::const_iterator it = m_info.begin(); - std::vector<ResultInfo>::const_iterator itEnd = m_info.end(); - for(; it != itEnd; ++it ) - m_reporter->Result( *it ); + { + std::vector<ScopedInfo*>::const_iterator it = m_scopedInfos.begin(); + std::vector<ScopedInfo*>::const_iterator itEnd = m_scopedInfos.end(); + for(; it != itEnd; ++it ) + m_reporter->Result( (*it)->getInfo() ); + } + { + std::vector<ResultInfo>::const_iterator it = m_info.begin(); + std::vector<ResultInfo>::const_iterator itEnd = m_info.end(); + for(; it != itEnd; ++it ) + m_reporter->Result( *it ); + } m_info.clear(); } diff --git a/include/internal/catch_stream.hpp b/include/internal/catch_stream.hpp index 653713a3..ee0890b8 100644 --- a/include/internal/catch_stream.hpp +++ b/include/internal/catch_stream.hpp @@ -58,6 +58,30 @@ namespace Catch { writeToDebugConsole( str ); } }; + + class Stream { + public: + Stream() + : streamBuf( NULL ), isOwned( false ) + {} + + Stream( std::streambuf* _streamBuf, bool _isOwned ) + : streamBuf( _streamBuf ), isOwned( _isOwned ) + {} + + void release() { + if( isOwned ) { + delete streamBuf; + streamBuf = NULL; + isOwned = false; + } + } + + std::streambuf* streamBuf; + + private: + bool isOwned; + }; } #endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED diff --git a/include/internal/catch_tags.hpp b/include/internal/catch_tags.hpp new file mode 100644 index 00000000..566181c8 --- /dev/null +++ b/include/internal/catch_tags.hpp @@ -0,0 +1,195 @@ +/* + * Created by Phil on 14/08/2012. + * Copyright 2012 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_TAGS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED + +#include <string> +#include <set> +#include <map> +#include <vector> + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + class TagParser { + public: + virtual ~TagParser(); + + void parse( const std::string& str ) { + std::size_t pos = 0; + while( pos < str.size() ) { + char c = str[pos]; + if( c == '[' ) { + std::size_t end = str.find_first_of( ']', pos ); + if( end != std::string::npos ) { + acceptTag( str.substr( pos+1, end-pos-1 ) ); + pos = end+1; + } + else { + acceptChar( c ); + pos++; + } + } + else { + acceptChar( c ); + pos++; + } + } + endParse(); + } + + protected: + virtual void acceptTag( const std::string& tag ) = 0; + virtual void acceptChar( char c ) = 0; + virtual void endParse() {} + + private: + }; + + class TagExtracter : public TagParser { + public: + + TagExtracter( std::set<std::string>& tags ) + : m_tags( tags ) + {} + virtual ~TagExtracter(); + + void parse( std::string& description ) { + TagParser::parse( description ); + description = m_remainder; + } + + private: + virtual void acceptTag( const std::string& tag ) { + m_tags.insert( tag ); + } + virtual void acceptChar( char c ) { + m_remainder += c; + } + + std::set<std::string>& m_tags; + std::string m_remainder; + }; + + class Tag { + public: + Tag() + : m_isNegated( false ) + {} + + Tag( const std::string& name, bool isNegated ) + : m_name( name ), + m_isNegated( isNegated ) + {} + + std::string getName() const { + return m_name; + } + bool isNegated() const { + return m_isNegated; + } + + bool operator ! () const { + return m_name.empty(); + } + + private: + std::string m_name; + bool m_isNegated; + }; + + class TagSet { + typedef std::map<std::string, Tag> TagMap; + public: + void add( const Tag& tag ) { + m_tags.insert( std::make_pair( tag.getName(), tag ) ); + } + + // needed? + Tag find( const std::string& name ) const { + TagMap::const_iterator it = m_tags.find( name ); + if( it == m_tags.end() ) + return Tag(); + else + return it->second; + } + bool empty() const { + return m_tags.empty(); + } + + bool matches( const std::set<std::string>& tags ) const { + TagMap::const_iterator it = m_tags.begin(); + TagMap::const_iterator itEnd = m_tags.end(); + for(; it != itEnd; ++it ) { + bool found = tags.find( it->first ) != tags.end(); + if( found == it->second.isNegated() ) + return false; + } + return true; + } + + private: + TagMap m_tags; + }; + + class TagExpression { + public: + bool matches( const std::set<std::string>& tags ) const { + std::vector<TagSet>::const_iterator it = m_tagSets.begin(); + std::vector<TagSet>::const_iterator itEnd = m_tagSets.end(); + for(; it != itEnd; ++it ) + if( it->matches( tags ) ) + return true; + return false; + } + + private: + friend class TagExpressionParser; + + std::vector<TagSet> m_tagSets; + }; + + class TagExpressionParser : public TagParser { + public: + TagExpressionParser( TagExpression& exp ) + : m_isNegated( false ), + m_exp( exp ) + {} + + ~TagExpressionParser(); + + private: + virtual void acceptTag( const std::string& tag ) { + m_currentTagSet.add( Tag( tag, m_isNegated ) ); + m_isNegated = false; + } + virtual void acceptChar( char c ) { + switch( c ) { + case '~': + m_isNegated = true; + break; + case ',': + m_exp.m_tagSets.push_back( m_currentTagSet ); + break; + } + } + virtual void endParse() { + if( !m_currentTagSet.empty() ) + m_exp.m_tagSets.push_back( m_currentTagSet ); + } + + bool m_isNegated; + TagSet m_currentTagSet; + TagExpression& m_exp; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED diff --git a/include/internal/catch_test_case_info.h b/include/internal/catch_test_case_info.h index 97857632..eee460a7 100644 --- a/include/internal/catch_test_case_info.h +++ b/include/internal/catch_test_case_info.h @@ -36,7 +36,8 @@ namespace Catch { const SourceLineInfo& getLineInfo() const; bool isHidden() const; bool hasTag( const std::string& tag ) const; - const std::set<std::string>& tags() const; + bool matchesTags( const std::string& tagPattern ) const; + const std::set<std::string>& getTags() const; void swap( TestCaseInfo& other ); bool operator == ( const TestCaseInfo& other ) const; diff --git a/include/internal/catch_test_case_info.hpp b/include/internal/catch_test_case_info.hpp index 413c43a4..38adac91 100644 --- a/include/internal/catch_test_case_info.hpp +++ b/include/internal/catch_test_case_info.hpp @@ -8,41 +8,13 @@ #ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED +#include "catch_tags.hpp" #include "catch_test_case_info.h" #include "catch_interfaces_testcase.h" namespace Catch { - namespace { - void extractTags( std::string& str, std::set<std::string>& tags ) { - std::string remainder; - std::size_t last = 0; - std::size_t begin = str.find_first_of( '[' ); - while( begin != std::string::npos ) { - std::size_t end = str.find_first_of( ']', begin ); - if( end != std::string::npos ) { - std::string tag = str.substr( begin+1, end-begin-1 ); - tags.insert( tag ); - if( begin - last > 0 ) - remainder += str.substr( last, begin-last ); - last = end+1; - } - else if( begin != str.size()-1 ) { - end = begin+1; - } - else { - break; - } - begin = str.find_first_of( '[', end ); - } - if( !tags.empty() ) { - if( last < str.size() ) - str = remainder + str.substr( last ); - else - str = remainder; - } - } - } + TestCaseInfo::TestCaseInfo( ITestCase* testCase, const char* name, const char* description, @@ -53,7 +25,7 @@ namespace Catch { m_lineInfo( lineInfo ), m_isHidden( startsWith( name, "./" ) ) { - extractTags( m_description, m_tags ); + TagExtracter( m_tags ).parse( m_description ); if( hasTag( "hide" ) ) m_isHidden = true; } @@ -106,7 +78,12 @@ namespace Catch { bool TestCaseInfo::hasTag( const std::string& tag ) const { return m_tags.find( tag ) != m_tags.end(); } - const std::set<std::string>& TestCaseInfo::tags() const { + bool TestCaseInfo::matchesTags( const std::string& tagPattern ) const { + TagExpression exp; + TagExpressionParser( exp ).parse( tagPattern ); + return exp.matches( m_tags ); + } + const std::set<std::string>& TestCaseInfo::getTags() const { return m_tags; } @@ -129,6 +106,7 @@ namespace Catch { swap( temp ); return *this; } -} + +} // end namespace Catch #endif // TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED diff --git a/include/internal/catch_test_spec.h b/include/internal/catch_test_spec.h index 07b0b98c..2c028d4e 100644 --- a/include/internal/catch_test_spec.h +++ b/include/internal/catch_test_spec.h @@ -9,6 +9,7 @@ #define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED #include "catch_test_case_info.h" +#include "catch_tags.hpp" #include <string> #include <vector> @@ -113,7 +114,24 @@ namespace Catch { m_inclusionFilters.push_back( filter ); } + void addTags( const std::string& tagPattern ) { + TagExpression exp; + TagExpressionParser( exp ).parse( tagPattern ); + + m_tagExpressions.push_back( exp ); + } + bool shouldInclude( const TestCaseInfo& testCase ) const { + if( !m_tagExpressions.empty() ) { + std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin(); + std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end(); + for(; it != itEnd; ++it ) + if( it->matches( testCase.getTags() ) ) + break; + if( it == itEnd ) + return false; + } + if( !m_inclusionFilters.empty() ) { std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin(); std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end(); @@ -123,7 +141,7 @@ namespace Catch { if( it == itEnd ) return false; } - else if( m_exclusionFilters.empty() ) { + else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) { return !testCase.isHidden(); } @@ -135,6 +153,7 @@ namespace Catch { return true; } private: + std::vector<TagExpression> m_tagExpressions; std::vector<TestCaseFilter> m_inclusionFilters; std::vector<TestCaseFilter> m_exclusionFilters; std::string m_name; diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp index a60428ee..5b102ffb 100644 --- a/projects/SelfTest/MiscTests.cpp +++ b/projects/SelfTest/MiscTests.cpp @@ -294,7 +294,13 @@ TEST_CASE( "empty", "An empty test with no assertions" ) { } -TEST_CASE( "Nice descriptive name", "[tag1][tag2][hide]" ) +TEST_CASE( "Nice descriptive name", "[tag1][tag2][tag3][hide]" ) { WARN( "This one ran" ); } +TEST_CASE( "first tag", "[tag1]" ) +{ +} +TEST_CASE( "second tag", "[tag2]" ) +{ +} diff --git a/projects/SelfTest/SurrogateCpps/catch_tags.cpp b/projects/SelfTest/SurrogateCpps/catch_tags.cpp new file mode 100644 index 00000000..47664eff --- /dev/null +++ b/projects/SelfTest/SurrogateCpps/catch_tags.cpp @@ -0,0 +1 @@ +#include "catch_tags.hpp" diff --git a/projects/SelfTest/TestMain.cpp b/projects/SelfTest/TestMain.cpp index f745f69b..b0fe11f5 100644 --- a/projects/SelfTest/TestMain.cpp +++ b/projects/SelfTest/TestMain.cpp @@ -247,8 +247,31 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) { REQUIRE( config.allowThrows == false ); } - } + + SECTION( "streams", "" ) { + SECTION( "-o filename", "" ) { + const char* argv[] = { "test", "-o", "filename.ext" }; + CHECK_NOTHROW( parseIntoConfig( argv, config ) ); + + REQUIRE( config.outputFilename == "filen |