Generate help from options objects

This commit is contained in:
Phil Nash 2012-08-27 12:19:07 +01:00
parent eb775aa7af
commit e7db40034c
2 changed files with 73 additions and 36 deletions

View File

@ -147,17 +147,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 << "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << 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( "/\\" );
@ -174,9 +169,7 @@ namespace Catch {
try { try {
CommandParser parser( argc, argv ); CommandParser parser( argc, argv );
AllOptions options; if( Command cmd = Options::HelpOptionParser().find( parser ) ) {
if( Command cmd = parser.find( "-h", "-?", "--help" ) ) {
if( cmd.argsCount() != 0 ) if( cmd.argsCount() != 0 )
cmd.raiseError( "Does not accept arguments" ); cmd.raiseError( "Does not accept arguments" );
@ -184,7 +177,9 @@ namespace Catch {
Catch::cleanUp(); Catch::cleanUp();
return 0; return 0;
} }
AllOptions options;
options.parseIntoConfig( parser, config.data() ); options.parseIntoConfig( parser, config.data() );
} }
catch( std::exception& ex ) { catch( std::exception& ex ) {

View File

@ -96,24 +96,46 @@ namespace Catch {
char const * const * m_argv; char const * const * m_argv;
}; };
class OptionParser : public IShared { class OptionParser : public SharedImpl<IShared> {
public: public:
virtual ~OptionParser() {} virtual ~OptionParser() {}
void parseIntoConfig( CommandParser parser, ConfigData& config ) { Command find( const CommandParser& parser ) const {
Command cmd; Command cmd;
for( std::vector<std::string>::const_iterator it = m_optionNames.begin(); for( std::vector<std::string>::const_iterator it = m_optionNames.begin();
it != m_optionNames.end(); it != m_optionNames.end();
++it ) ++it )
cmd += parser.find( *it ); cmd += parser.find( *it );
return cmd;
}
if( cmd ) void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
if( Command cmd = find( parser ) )
parseIntoConfig( cmd, config ); parseIntoConfig( cmd, config );
} }
virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0; virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0;
virtual std::string argsSynopsis() const = 0; virtual std::string argsSynopsis() const = 0;
virtual std::string optionSummary() 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: protected:
std::vector<std::string> m_optionNames; std::vector<std::string> m_optionNames;
@ -121,6 +143,25 @@ namespace Catch {
namespace Options { 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 { class TestCaseOptionParser : public OptionParser {
public: public:
TestCaseOptionParser() { TestCaseOptionParser() {
@ -164,7 +205,7 @@ namespace Catch {
m_optionNames.push_back( "--list" ); m_optionNames.push_back( "--list" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "[all | tests | reporters [xml]]";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -203,7 +244,7 @@ namespace Catch {
m_optionNames.push_back( "--reporter" ); m_optionNames.push_back( "--reporter" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "<reporter name>";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -223,7 +264,7 @@ namespace Catch {
m_optionNames.push_back( "--out" ); m_optionNames.push_back( "--out" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "<file name>|<%stream name>";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -246,7 +287,7 @@ namespace Catch {
m_optionNames.push_back( "--success" ); m_optionNames.push_back( "--success" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -266,7 +307,7 @@ namespace Catch {
m_optionNames.push_back( "--break" ); m_optionNames.push_back( "--break" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -286,7 +327,7 @@ namespace Catch {
m_optionNames.push_back( "--name" ); m_optionNames.push_back( "--name" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "<name>";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -306,7 +347,7 @@ namespace Catch {
m_optionNames.push_back( "--abort" ); m_optionNames.push_back( "--abort" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "[#]";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -334,7 +375,7 @@ namespace Catch {
m_optionNames.push_back( "--nothrow" ); m_optionNames.push_back( "--nothrow" );
} }
virtual std::string argsSynopsis() const { virtual std::string argsSynopsis() const {
return "!TBD"; return "";
} }
virtual std::string optionSummary() const { virtual std::string optionSummary() const {
return "!TBD"; return "!TBD";
@ -355,16 +396,17 @@ namespace Catch {
typedef Parsers::const_iterator const_iterator; typedef Parsers::const_iterator const_iterator;
typedef Parsers::const_iterator iterator; typedef Parsers::const_iterator iterator;
AllOptions() { AllOptions() {
add<Options::AbortOptionParser>();
add<Options::DebugBreakOptionParser>();
add<Options::ListOptionParser>();
add<Options::NameOptionParser>();
add<Options::NoThrowOptionParser>();
add<Options::OutputOptionParser>();
add<Options::ReporterOptionParser>();
add<Options::SuccesssOptionParser>();
add<Options::TestCaseOptionParser>(); 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 ) { void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
@ -382,7 +424,7 @@ namespace Catch {
template<typename T> template<typename T>
void add() { void add() {
m_parsers.push_back( new SharedImpl<T>() ); m_parsers.push_back( new T() );
} }
Parsers m_parsers; Parsers m_parsers;