mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-26 23:36:11 +01:00
Option objects now enforce min/ max args generically
This commit is contained in:
parent
e7db40034c
commit
ecf934b045
@ -152,7 +152,7 @@ namespace Catch {
|
|||||||
OptionParser& opt = **it;
|
OptionParser& opt = **it;
|
||||||
os << " " << opt.optionNames() << " " << opt.argsSynopsis() << "\n";
|
os << " " << opt.optionNames() << " " << opt.argsSynopsis() << "\n";
|
||||||
}
|
}
|
||||||
os << "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl;
|
os << "\nFor more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line\n" << std::endl;
|
||||||
}
|
}
|
||||||
inline void showHelp( std::string exeName ) {
|
inline void showHelp( std::string exeName ) {
|
||||||
std::string::size_type pos = exeName.find_last_of( "/\\" );
|
std::string::size_type pos = exeName.find_last_of( "/\\" );
|
||||||
|
@ -17,7 +17,8 @@ namespace Catch {
|
|||||||
public:
|
public:
|
||||||
Command(){}
|
Command(){}
|
||||||
|
|
||||||
explicit Command( const std::string& name ) : m_name( name ) {}
|
explicit Command( const std::string& name ) : m_name( name ) {
|
||||||
|
}
|
||||||
|
|
||||||
Command& operator += ( const std::string& arg ) {
|
Command& operator += ( const std::string& arg ) {
|
||||||
m_args.push_back( arg );
|
m_args.push_back( arg );
|
||||||
@ -46,9 +47,13 @@ namespace Catch {
|
|||||||
CATCH_ATTRIBUTE_NORETURN
|
CATCH_ATTRIBUTE_NORETURN
|
||||||
void raiseError( const std::string& message ) const {
|
void raiseError( const std::string& message ) const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Error while parsing " << m_name << ". " << message << ".";
|
if( m_name.empty() )
|
||||||
|
oss << "Error while parsing " << m_name << ". " << message << ".";
|
||||||
|
else
|
||||||
|
oss << "Error while parsing arguments. " << message << ".";
|
||||||
|
|
||||||
if( m_args.size() > 0 )
|
if( m_args.size() > 0 )
|
||||||
oss << " Arguments where:";
|
oss << " Arguments were:";
|
||||||
for( std::size_t i = 0; i < m_args.size(); ++i )
|
for( std::size_t i = 0; i < m_args.size(); ++i )
|
||||||
oss << " " << m_args[i];
|
oss << " " << m_args[i];
|
||||||
throw std::domain_error( oss.str() );
|
throw std::domain_error( oss.str() );
|
||||||
@ -98,6 +103,10 @@ namespace Catch {
|
|||||||
|
|
||||||
class OptionParser : public SharedImpl<IShared> {
|
class OptionParser : public SharedImpl<IShared> {
|
||||||
public:
|
public:
|
||||||
|
OptionParser( int minArgs = 0, int maxArgs = 0 )
|
||||||
|
: m_minArgs( minArgs ), m_maxArgs( maxArgs )
|
||||||
|
{}
|
||||||
|
|
||||||
virtual ~OptionParser() {}
|
virtual ~OptionParser() {}
|
||||||
|
|
||||||
Command find( const CommandParser& parser ) const {
|
Command find( const CommandParser& parser ) const {
|
||||||
@ -109,9 +118,24 @@ namespace Catch {
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void validateArgs( const Command& args ) const {
|
||||||
|
if( tooFewArgs( args ) || tooManyArgs( args ) ) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
if( m_maxArgs == -1 )
|
||||||
|
oss <<"Expected at least " << pluralise( static_cast<std::size_t>( m_minArgs ), "argument" );
|
||||||
|
else if( m_minArgs == m_maxArgs )
|
||||||
|
oss <<"Expected " << pluralise( static_cast<std::size_t>( m_minArgs ), "argument" );
|
||||||
|
else
|
||||||
|
oss <<"Expected between " << m_minArgs << " and " << m_maxArgs << " argument";
|
||||||
|
args.raiseError( oss.str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
|
void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
|
||||||
if( Command cmd = find( parser ) )
|
if( Command cmd = find( parser ) ) {
|
||||||
|
validateArgs( cmd );
|
||||||
parseIntoConfig( cmd, config );
|
parseIntoConfig( cmd, config );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0;
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0;
|
||||||
@ -138,7 +162,16 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
bool tooFewArgs( const Command& args ) const {
|
||||||
|
return args.argsCount() < static_cast<std::size_t>( m_minArgs );
|
||||||
|
}
|
||||||
|
bool tooManyArgs( const Command& args ) const {
|
||||||
|
return m_maxArgs >= 0 && args.argsCount() > static_cast<std::size_t>( m_maxArgs );
|
||||||
|
}
|
||||||
std::vector<std::string> m_optionNames;
|
std::vector<std::string> m_optionNames;
|
||||||
|
int m_minArgs;
|
||||||
|
int m_maxArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
@ -164,7 +197,7 @@ namespace Catch {
|
|||||||
|
|
||||||
class TestCaseOptionParser : public OptionParser {
|
class TestCaseOptionParser : public OptionParser {
|
||||||
public:
|
public:
|
||||||
TestCaseOptionParser() {
|
TestCaseOptionParser() : OptionParser( 1, -1 ) {
|
||||||
m_optionNames.push_back( "-t" );
|
m_optionNames.push_back( "-t" );
|
||||||
m_optionNames.push_back( "--test" );
|
m_optionNames.push_back( "--test" );
|
||||||
m_optionNames.push_back( "" ); // default option
|
m_optionNames.push_back( "" ); // default option
|
||||||
@ -177,8 +210,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() == 0 )
|
|
||||||
cmd.raiseError( "Expected at least one argument" );
|
|
||||||
std::string groupName;
|
std::string groupName;
|
||||||
for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
|
for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
|
||||||
if( i != 0 )
|
if( i != 0 )
|
||||||
@ -200,7 +231,7 @@ namespace Catch {
|
|||||||
|
|
||||||
class ListOptionParser : public OptionParser {
|
class ListOptionParser : public OptionParser {
|
||||||
public:
|
public:
|
||||||
ListOptionParser() {
|
ListOptionParser() : OptionParser( 0, 2 ) {
|
||||||
m_optionNames.push_back( "-l" );
|
m_optionNames.push_back( "-l" );
|
||||||
m_optionNames.push_back( "--list" );
|
m_optionNames.push_back( "--list" );
|
||||||
}
|
}
|
||||||
@ -212,9 +243,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() > 2 )
|
|
||||||
cmd.raiseError( "Expected upto 2 arguments" );
|
|
||||||
|
|
||||||
config.listSpec = List::TestNames;
|
config.listSpec = List::TestNames;
|
||||||
if( cmd.argsCount() >= 1 ) {
|
if( cmd.argsCount() >= 1 ) {
|
||||||
if( cmd[0] == "all" )
|
if( cmd[0] == "all" )
|
||||||
@ -239,7 +267,7 @@ namespace Catch {
|
|||||||
|
|
||||||
class ReporterOptionParser : public OptionParser {
|
class ReporterOptionParser : public OptionParser {
|
||||||
public:
|
public:
|
||||||
ReporterOptionParser() {
|
ReporterOptionParser() : OptionParser( 1, 1 ) {
|
||||||
m_optionNames.push_back( "-r" );
|
m_optionNames.push_back( "-r" );
|
||||||
m_optionNames.push_back( "--reporter" );
|
m_optionNames.push_back( "--reporter" );
|
||||||
}
|
}
|
||||||
@ -251,15 +279,13 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() != 1 )
|
|
||||||
cmd.raiseError( "Expected one argument" );
|
|
||||||
config.reporter = cmd[0];
|
config.reporter = cmd[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OutputOptionParser : public OptionParser {
|
class OutputOptionParser : public OptionParser {
|
||||||
public:
|
public:
|
||||||
OutputOptionParser() {
|
OutputOptionParser() : OptionParser( 1, 1 ) {
|
||||||
m_optionNames.push_back( "-o" );
|
m_optionNames.push_back( "-o" );
|
||||||
m_optionNames.push_back( "--out" );
|
m_optionNames.push_back( "--out" );
|
||||||
}
|
}
|
||||||
@ -271,8 +297,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() == 0 )
|
|
||||||
cmd.raiseError( "Expected filename" );
|
|
||||||
if( cmd[0][0] == '%' )
|
if( cmd[0][0] == '%' )
|
||||||
config.stream = cmd[0].substr( 1 );
|
config.stream = cmd[0].substr( 1 );
|
||||||
else
|
else
|
||||||
@ -294,8 +318,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() != 0 )
|
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
|
||||||
config.includeWhichResults = Include::SuccessfulResults;
|
config.includeWhichResults = Include::SuccessfulResults;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -314,15 +336,13 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() != 0 )
|
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
|
||||||
config.shouldDebugBreak = true;
|
config.shouldDebugBreak = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NameOptionParser : public OptionParser {
|
class NameOptionParser : public OptionParser {
|
||||||
public:
|
public:
|
||||||
NameOptionParser() {
|
NameOptionParser() : OptionParser( 1, 1 ) {
|
||||||
m_optionNames.push_back( "-n" );
|
m_optionNames.push_back( "-n" );
|
||||||
m_optionNames.push_back( "--name" );
|
m_optionNames.push_back( "--name" );
|
||||||
}
|
}
|
||||||
@ -334,15 +354,13 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() != 1 )
|
|
||||||
cmd.raiseError( "Expected a name" );
|
|
||||||
config.name = cmd[0];
|
config.name = cmd[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbortOptionParser : public OptionParser {
|
class AbortOptionParser : public OptionParser {
|
||||||
public:
|
public:
|
||||||
AbortOptionParser() {
|
AbortOptionParser() : OptionParser( 0, 1 ) {
|
||||||
m_optionNames.push_back( "-a" );
|
m_optionNames.push_back( "-a" );
|
||||||
m_optionNames.push_back( "--abort" );
|
m_optionNames.push_back( "--abort" );
|
||||||
}
|
}
|
||||||
@ -354,8 +372,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() > 1 )
|
|
||||||
cmd.raiseError( "Only accepts 0-1 arguments" );
|
|
||||||
int threshold = 1;
|
int threshold = 1;
|
||||||
if( cmd.argsCount() == 1 ) {
|
if( cmd.argsCount() == 1 ) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@ -382,8 +398,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() != 0 )
|
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
|
||||||
config.allowThrows = false;
|
config.allowThrows = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -159,7 +159,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) {
|
|||||||
|
|
||||||
SECTION( "-t/0", "When no test names are supplied it is an error" ) {
|
SECTION( "-t/0", "When no test names are supplied it is an error" ) {
|
||||||
const char* argv[] = { "test", "-t" };
|
const char* argv[] = { "test", "-t" };
|
||||||
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "at least one" ) );
|
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "at least 1" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) {
|
|||||||
}
|
}
|
||||||
SECTION( "-r/error", "reporter config only accepts one argument" ) {
|
SECTION( "-r/error", "reporter config only accepts one argument" ) {
|
||||||
const char* argv[] = { "test", "-r", "one", "two" };
|
const char* argv[] = { "test", "-r", "one", "two" };
|
||||||
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "one argument" ) );
|
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "1 argument" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) {
|
|||||||
}
|
}
|
||||||
SECTION( "-b", "break option has no arguments" ) {
|
SECTION( "-b", "break option has no arguments" ) {
|
||||||
const char* argv[] = { "test", "-b", "unexpected" };
|
const char* argv[] = { "test", "-b", "unexpected" };
|
||||||
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "not accept" ) );
|
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "0 arguments" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) {
|
|||||||
}
|
}
|
||||||
SECTION( "-a/error/two args", "cutoff only takes one argument" ) {
|
SECTION( "-a/error/two args", "cutoff only takes one argument" ) {
|
||||||
const char* argv[] = { "test", "-a", "1", "2" };
|
const char* argv[] = { "test", "-a", "1", "2" };
|
||||||
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "accepts" ) );
|
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "0 and 1 argument" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Generated: 2012-08-24 19:01:02.483106
|
* Generated: 2012-08-27 21:42:22.556899
|
||||||
* ----------------------------------------------------------
|
* ----------------------------------------------------------
|
||||||
* This file has been merged from multiple headers. Please don't edit it directly
|
* This file has been merged from multiple headers. Please don't edit it directly
|
||||||
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
||||||
@ -2480,7 +2480,8 @@ namespace Catch {
|
|||||||
public:
|
public:
|
||||||
Command(){}
|
Command(){}
|
||||||
|
|
||||||
explicit Command( const std::string& name ) : m_name( name ) {}
|
explicit Command( const std::string& name ) : m_name( name ) {
|
||||||
|
}
|
||||||
|
|
||||||
Command& operator += ( const std::string& arg ) {
|
Command& operator += ( const std::string& arg ) {
|
||||||
m_args.push_back( arg );
|
m_args.push_back( arg );
|
||||||
@ -2509,9 +2510,13 @@ namespace Catch {
|
|||||||
CATCH_ATTRIBUTE_NORETURN
|
CATCH_ATTRIBUTE_NORETURN
|
||||||
void raiseError( const std::string& message ) const {
|
void raiseError( const std::string& message ) const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Error while parsing " << m_name << ". " << message << ".";
|
if( m_name.empty() )
|
||||||
|
oss << "Error while parsing " << m_name << ". " << message << ".";
|
||||||
|
else
|
||||||
|
oss << "Error while parsing arguments. " << message << ".";
|
||||||
|
|
||||||
if( m_args.size() > 0 )
|
if( m_args.size() > 0 )
|
||||||
oss << " Arguments where:";
|
oss << " Arguments were:";
|
||||||
for( std::size_t i = 0; i < m_args.size(); ++i )
|
for( std::size_t i = 0; i < m_args.size(); ++i )
|
||||||
oss << " " << m_args[i];
|
oss << " " << m_args[i];
|
||||||
throw std::domain_error( oss.str() );
|
throw std::domain_error( oss.str() );
|
||||||
@ -2535,9 +2540,12 @@ namespace Catch {
|
|||||||
return find( shortArg ) + find( longArg );
|
return find( shortArg ) + find( longArg );
|
||||||
}
|
}
|
||||||
Command find( const std::string& arg ) const {
|
Command find( const std::string& arg ) const {
|
||||||
for( std::size_t i = 1; i < m_argc; ++i )
|
if( arg.empty() )
|
||||||
if( m_argv[i] == arg )
|
return getArgs( "", 1 );
|
||||||
return getArgs( m_argv[i], i+1 );
|
else
|
||||||
|
for( std::size_t i = 1; i < m_argc; ++i )
|
||||||
|
if( m_argv[i] == arg )
|
||||||
|
return getArgs( m_argv[i], i+1 );
|
||||||
return Command();
|
return Command();
|
||||||
}
|
}
|
||||||
Command getDefaultArgs() const {
|
Command getDefaultArgs() const {
|
||||||
@ -2556,109 +2564,349 @@ namespace Catch {
|
|||||||
char const * const * m_argv;
|
char const * const * m_argv;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
|
class OptionParser : public SharedImpl<IShared> {
|
||||||
|
public:
|
||||||
|
OptionParser( int minArgs = 0, int maxArgs = 0 )
|
||||||
|
: m_minArgs( minArgs ), m_maxArgs( maxArgs )
|
||||||
|
{}
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-l", "--list" ) ) {
|
virtual ~OptionParser() {}
|
||||||
if( cmd.argsCount() > 2 )
|
|
||||||
cmd.raiseError( "Expected upto 2 arguments" );
|
|
||||||
|
|
||||||
config.listSpec = List::TestNames;
|
Command find( const CommandParser& parser ) const {
|
||||||
if( cmd.argsCount() >= 1 ) {
|
Command cmd;
|
||||||
if( cmd[0] == "all" )
|
for( std::vector<std::string>::const_iterator it = m_optionNames.begin();
|
||||||
config.listSpec = List::All;
|
it != m_optionNames.end();
|
||||||
else if( cmd[0] == "tests" )
|
++it )
|
||||||
config.listSpec = List::Tests;
|
cmd += parser.find( *it );
|
||||||
else if( cmd[0] == "reporters" )
|
return cmd;
|
||||||
config.listSpec = List::Reports;
|
}
|
||||||
|
|
||||||
|
void validateArgs( const Command& args ) const {
|
||||||
|
if( tooFewArgs( args ) || tooManyArgs( args ) ) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
if( m_maxArgs == -1 )
|
||||||
|
oss <<"Expected at least " << pluralise( static_cast<std::size_t>( m_minArgs ), "argument" );
|
||||||
|
else if( m_minArgs == m_maxArgs )
|
||||||
|
oss <<"Expected " << pluralise( static_cast<std::size_t>( m_minArgs ), "argument" );
|
||||||
else
|
else
|
||||||
cmd.raiseError( "Expected [tests] or [reporters]" );
|
oss <<"Expected between " << m_minArgs << " and " << m_maxArgs << " argument";
|
||||||
|
args.raiseError( oss.str() );
|
||||||
}
|
}
|
||||||
if( cmd.argsCount() >= 2 ) {
|
}
|
||||||
if( cmd[1] == "xml" )
|
|
||||||
config.listSpec = static_cast<List::What>( config.listSpec | List::AsXml );
|
void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
|
||||||
else if( cmd[1] == "text" )
|
if( Command cmd = find( parser ) ) {
|
||||||
config.listSpec = static_cast<List::What>( config.listSpec | List::AsText );
|
validateArgs( cmd );
|
||||||
|
parseIntoConfig( cmd, config );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0;
|
||||||
|
virtual std::string argsSynopsis() const = 0;
|
||||||
|
virtual std::string optionSummary() const = 0;
|
||||||
|
|
||||||
|
std::string optionNames() const {
|
||||||
|
std::string names;
|
||||||
|
for( std::vector<std::string>::const_iterator it = m_optionNames.begin();
|
||||||
|
it != m_optionNames.end();
|
||||||
|
++it ) {
|
||||||
|
if( !it->empty() ) {
|
||||||
|
if( !names.empty() )
|
||||||
|
names += ", ";
|
||||||
|
names += *it;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
names = "[" + names;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( names[0] == '[' )
|
||||||
|
names += "]";
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool tooFewArgs( const Command& args ) const {
|
||||||
|
return args.argsCount() < static_cast<std::size_t>( m_minArgs );
|
||||||
|
}
|
||||||
|
bool tooManyArgs( const Command& args ) const {
|
||||||
|
return m_maxArgs >= 0 && args.argsCount() > static_cast<std::size_t>( m_maxArgs );
|
||||||
|
}
|
||||||
|
std::vector<std::string> m_optionNames;
|
||||||
|
int m_minArgs;
|
||||||
|
int m_maxArgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Options {
|
||||||
|
|
||||||
|
class HelpOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
HelpOptionParser() {
|
||||||
|
m_optionNames.push_back( "-?" );
|
||||||
|
m_optionNames.push_back( "-h" );
|
||||||
|
m_optionNames.push_back( "--help" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "Shows this usage summary";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command&, ConfigData& ) {
|
||||||
|
// Does not affect config
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestCaseOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
TestCaseOptionParser() : OptionParser( 1, -1 ) {
|
||||||
|
m_optionNames.push_back( "-t" );
|
||||||
|
m_optionNames.push_back( "--test" );
|
||||||
|
m_optionNames.push_back( "" ); // default option
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "<testspec> [<testspec>...]";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "Specify which test case or cases to run";
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ) {
|
||||||
|
if( startsWith( cmd[i], "exclude:" ) )
|
||||||
|
filters.addFilter( TestCaseFilter( cmd[i].substr( 8 ), IfFilterMatches::ExcludeTests ) );
|
||||||
|
else if( startsWith( cmd[i], "~" ) )
|
||||||
|
filters.addFilter( TestCaseFilter( cmd[i].substr( 1 ), IfFilterMatches::ExcludeTests ) );
|
||||||
|
else
|
||||||
|
filters.addFilter( TestCaseFilter( cmd[i] ) );
|
||||||
|
}
|
||||||
|
config.filters.push_back( filters );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
ListOptionParser() : OptionParser( 0, 2 ) {
|
||||||
|
m_optionNames.push_back( "-l" );
|
||||||
|
m_optionNames.push_back( "--list" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "[all | tests | reporters [xml]]";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
config.listSpec = List::TestNames;
|
||||||
|
if( cmd.argsCount() >= 1 ) {
|
||||||
|
if( cmd[0] == "all" )
|
||||||
|
config.listSpec = List::All;
|
||||||
|
else if( cmd[0] == "tests" )
|
||||||
|
config.listSpec = List::Tests;
|
||||||
|
else if( cmd[0] == "reporters" )
|
||||||
|
config.listSpec = List::Reports;
|
||||||
|
else
|
||||||
|
cmd.raiseError( "Expected [tests] or [reporters]" );
|
||||||
|
}
|
||||||
|
if( cmd.argsCount() >= 2 ) {
|
||||||
|
if( cmd[1] == "xml" )
|
||||||
|
config.listSpec = static_cast<List::What>( config.listSpec | List::AsXml );
|
||||||
|
else if( cmd[1] == "text" )
|
||||||
|
config.listSpec = static_cast<List::What>( config.listSpec | List::AsText );
|
||||||
|
else
|
||||||
|
cmd.raiseError( "Expected [xml] or [text]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReporterOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
ReporterOptionParser() : OptionParser( 1, 1 ) {
|
||||||
|
m_optionNames.push_back( "-r" );
|
||||||
|
m_optionNames.push_back( "--reporter" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "<reporter name>";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
config.reporter = cmd[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OutputOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
OutputOptionParser() : OptionParser( 1, 1 ) {
|
||||||
|
m_optionNames.push_back( "-o" );
|
||||||
|
m_optionNames.push_back( "--out" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "<file name>|<%stream name>";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
if( cmd[0][0] == '%' )
|
||||||
|
config.stream = cmd[0].substr( 1 );
|
||||||
else
|
else
|
||||||
cmd.raiseError( "Expected [xml] or [text]" );
|
config.outputFilename = cmd[0];
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-t", "--test" ) + parser.getDefaultArgs() ) {
|
class SuccesssOptionParser : public OptionParser {
|
||||||
if( cmd.argsCount() == 0 )
|
public:
|
||||||
cmd.raiseError( "Expected at least one argument" );
|
SuccesssOptionParser() {
|
||||||
std::string groupName;
|
m_optionNames.push_back( "-s" );
|
||||||
for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
|
m_optionNames.push_back( "--success" );
|
||||||
if( i != 0 )
|
|
||||||
groupName += " ";
|
|
||||||
groupName += cmd[i];
|
|
||||||
}
|
}
|
||||||
TestCaseFilters filters( groupName );
|
virtual std::string argsSynopsis() const {
|
||||||
for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
|
return "";
|
||||||
if( startsWith( cmd[i], "exclude:" ) )
|
|
||||||
filters.addFilter( TestCaseFilter( cmd[i].substr( 8 ), IfFilterMatches::ExcludeTests ) );
|
|
||||||
else if( startsWith( cmd[i], "~" ) )
|
|
||||||
filters.addFilter( TestCaseFilter( cmd[i].substr( 1 ), IfFilterMatches::ExcludeTests ) );
|
|
||||||
else
|
|
||||||
filters.addFilter( TestCaseFilter( cmd[i] ) );
|
|
||||||
}
|
}
|
||||||
config.filters.push_back( filters );
|
virtual std::string optionSummary() const {
|
||||||
}
|
return "!TBD";
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-r", "--reporter" ) ) {
|
|
||||||
if( cmd.argsCount() != 1 )
|
|
||||||
cmd.raiseError( "Expected one argument" );
|
|
||||||
config.reporter = cmd[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-o", "--out" ) ) {
|
|
||||||
if( cmd.argsCount() == 0 )
|
|
||||||
cmd.raiseError( "Expected filename" );
|
|
||||||
if( cmd[0][0] == '%' )
|
|
||||||
config.stream = cmd[0].substr( 1 );
|
|
||||||
else
|
|
||||||
config.outputFilename = cmd[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-s", "--success" ) ) {
|
|
||||||
if( cmd.argsCount() != 0 )
|
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
|
||||||
config.includeWhichResults = Include::SuccessfulResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-b", "--break" ) ) {
|
|
||||||
if( cmd.argsCount() != 0 )
|
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
|
||||||
config.shouldDebugBreak = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-n", "--name" ) ) {
|
|
||||||
if( cmd.argsCount() != 1 )
|
|
||||||
cmd.raiseError( "Expected a name" );
|
|
||||||
config.name = cmd[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-a", "--abort" ) ) {
|
|
||||||
if( cmd.argsCount() > 1 )
|
|
||||||
cmd.raiseError( "Only accepts 0-1 arguments" );
|
|
||||||
int threshold = 1;
|
|
||||||
if( cmd.argsCount() == 1 ) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << cmd[0];
|
|
||||||
ss >> threshold;
|
|
||||||
if( ss.fail() || threshold <= 0 )
|
|
||||||
cmd.raiseError( "threshold must be a number greater than zero" );
|
|
||||||
}
|
}
|
||||||
config.cutoff = threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-nt", "--nothrow" ) ) {
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
if( cmd.argsCount() != 0 )
|
config.includeWhichResults = Include::SuccessfulResults;
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
}
|
||||||
config.allowThrows = false;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
class DebugBreakOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
DebugBreakOptionParser() {
|
||||||
|
m_optionNames.push_back( "-b" );
|
||||||
|
m_optionNames.push_back( "--break" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
config.shouldDebugBreak = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NameOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
NameOptionParser() : OptionParser( 1, 1 ) {
|
||||||
|
m_optionNames.push_back( "-n" );
|
||||||
|
m_optionNames.push_back( "--name" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "<name>";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
config.name = cmd[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AbortOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
AbortOptionParser() : OptionParser( 0, 1 ) {
|
||||||
|
m_optionNames.push_back( "-a" );
|
||||||
|
m_optionNames.push_back( "--abort" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "[#]";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
int threshold = 1;
|
||||||
|
if( cmd.argsCount() == 1 ) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << cmd[0];
|
||||||
|
ss >> threshold;
|
||||||
|
if( ss.fail() || threshold <= 0 )
|
||||||
|
cmd.raiseError( "threshold must be a number greater than zero" );
|
||||||
|
}
|
||||||
|
config.cutoff = threshold;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NoThrowOptionParser : public OptionParser {
|
||||||
|
public:
|
||||||
|
NoThrowOptionParser() {
|
||||||
|
m_optionNames.push_back( "-nt" );
|
||||||
|
m_optionNames.push_back( "--nothrow" );
|
||||||
|
}
|
||||||
|
virtual std::string argsSynopsis() const {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
virtual std::string optionSummary() const {
|
||||||
|
return "!TBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
|
||||||
|
config.allowThrows = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AllOptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<Ptr<OptionParser> > Parsers;
|
||||||
|
typedef Parsers::const_iterator const_iterator;
|
||||||
|
typedef Parsers::const_iterator iterator;
|
||||||
|
|
||||||
|
AllOptions() {
|
||||||
|
add<Options::TestCaseOptionParser>();
|
||||||
|
add<Options::ListOptionParser>();
|
||||||
|
add<Options::ReporterOptionParser>();
|
||||||
|
add<Options::OutputOptionParser>();
|
||||||
|
add<Options::SuccesssOptionParser>();
|
||||||
|
add<Options::DebugBreakOptionParser>();
|
||||||
|
add<Options::NameOptionParser>();
|
||||||
|
add<Options::AbortOptionParser>();
|
||||||
|
add<Options::NoThrowOptionParser>();
|
||||||
|
add<Options::HelpOptionParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
|
||||||
|
for( const_iterator it = m_parsers.begin(); it != m_parsers.end(); ++it )
|
||||||
|
(*it)->parseIntoConfig( parser, config );
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const {
|
||||||
|
return m_parsers.begin();
|
||||||
|
}
|
||||||
|
const_iterator end() const {
|
||||||
|
return m_parsers.end();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void add() {
|
||||||
|
m_parsers.push_back( new T() );
|
||||||
|
}
|
||||||
|
Parsers m_parsers;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
// #included from: internal/catch_list.hpp
|
// #included from: internal/catch_list.hpp
|
||||||
@ -3307,17 +3555,12 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void showUsage( std::ostream& os ) {
|
inline void showUsage( std::ostream& os ) {
|
||||||
os << "\t-?, -h, --help\n"
|
AllOptions options;
|
||||||
<< "\t-l, --list [all | tests | reporters [xml]]\n"
|
for( AllOptions::const_iterator it = options.begin(); it != options.end(); ++it ) {
|
||||||
<< "\t-t, --test <testspec> [<testspec>...]\n"
|
OptionParser& opt = **it;
|
||||||
<< "\t-r, --reporter <reporter name>\n"
|
os << " " << opt.optionNames() << " " << opt.argsSynopsis() << "\n";
|
||||||
<< "\t-o, --out <file name>|<%stream name>\n"
|
}
|
||||||
<< "\t-s, --success\n"
|
os << "\nFor more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line\n" << std::endl;
|
||||||
<< "\t-b, --break\n"
|
|
||||||
<< "\t-n, --name <name>\n"
|
|
||||||
<< "\t-a, --abort [#]\n"
|
|
||||||
<< "\t-nt, --nothrow\n\n"
|
|
||||||
<< "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl;
|
|
||||||
}
|
}
|
||||||
inline void showHelp( std::string exeName ) {
|
inline void showHelp( std::string exeName ) {
|
||||||
std::string::size_type pos = exeName.find_last_of( "/\\" );
|
std::string::size_type pos = exeName.find_last_of( "/\\" );
|
||||||
@ -3334,7 +3577,7 @@ namespace Catch {
|
|||||||
try {
|
try {
|
||||||
CommandParser parser( argc, argv );
|
CommandParser parser( argc, argv );
|
||||||
|
|
||||||
if( Command cmd = parser.find( "-h", "-?", "--help" ) ) {
|
if( Command cmd = Options::HelpOptionParser().find( parser ) ) {
|
||||||
if( cmd.argsCount() != 0 )
|
if( cmd.argsCount() != 0 )
|
||||||
cmd.raiseError( "Does not accept arguments" );
|
cmd.raiseError( "Does not accept arguments" );
|
||||||
|
|
||||||
@ -3343,7 +3586,9 @@ namespace Catch {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseIntoConfig( parser, config.data() );
|
AllOptions options;
|
||||||
|
|
||||||
|
options.parseIntoConfig( parser, config.data() );
|
||||||
}
|
}
|
||||||
catch( std::exception& ex ) {
|
catch( std::exception& ex ) {
|
||||||
std::cerr << ex.what() << "\n\nUsage: ...\n\n";
|
std::cerr << ex.what() << "\n\nUsage: ...\n\n";
|
||||||
|
Loading…
Reference in New Issue
Block a user