New version of Clara.

- updated command line setup with new API
- updated STITCH macros
- force embedded Clara to use Catch’s console width (but restore it after)
- remove command line tests (as these have now moved into the Clara project)
This commit is contained in:
Phil Nash 2014-03-06 08:16:06 +00:00
parent 1f1ee3c63d
commit b9fea75109
6 changed files with 348 additions and 406 deletions

View File

@ -9,12 +9,24 @@
#ifndef TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
// Use Catch's value for console width (store Clara's off to the side, if present)
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
#undef CLARA_CONFIG_CONSOLE_WIDTH
#endif
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
// Declare Clara inside the Catch namespace
#define STITCH_CLARA_OUTER_NAMESPACE Catch
#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
#include "clara.h"
#undef STITCH_CLARA_OUTER_NAMESPACE
#undef STITCH_CLARA_OPEN_NAMESPACE
// Restore Clara's value for console width, if present
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#endif
#endif // TWOBLUECUBES_CATCH_CLARA_H_INCLUDED

View File

@ -55,108 +55,95 @@ namespace Catch {
inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
Clara::CommandLine<ConfigData> cli;
using namespace Clara;
CommandLine<ConfigData> cli;
cli.bindProcessName( &ConfigData::processName );
cli.bind( &ConfigData::showHelp )
cli["-?"]["-h"]["--help"]
.describe( "display usage information" )
.shortOpt( "?")
.shortOpt( "h")
.longOpt( "help" );
.into( &ConfigData::showHelp );
cli.bind( &ConfigData::listTests )
cli["-l"]["--list-tests"]
.describe( "list all/matching test cases" )
.shortOpt( "l")
.longOpt( "list-tests" );
.into( &ConfigData::listTests );
cli.bind( &ConfigData::listTags )
cli["-t"]["--list-tags"]
.describe( "list all/matching tags" )
.shortOpt( "t")
.longOpt( "list-tags" );
.into( &ConfigData::listTags );
cli.bind( &ConfigData::showSuccessfulTests )
cli["-s"]["--success"]
.describe( "include successful tests in output" )
.shortOpt( "s")
.longOpt( "success" );
.into( &ConfigData::showSuccessfulTests );
cli.bind( &ConfigData::shouldDebugBreak )
cli["-b"]["--break"]
.describe( "break into debugger on failure" )
.shortOpt( "b")
.longOpt( "break" );
.into( &ConfigData::shouldDebugBreak );
cli.bind( &ConfigData::noThrow )
cli["-e"]["--nothrow"]
.describe( "skip exception tests" )
.shortOpt( "e")
.longOpt( "nothrow" );
.into( &ConfigData::noThrow );
cli.bind( &ConfigData::outputFilename )
cli["-o"]["--out"]
.placeholder( "filename" )
.describe( "output filename" )
.shortOpt( "o")
.longOpt( "out" )
.hint( "filename" );
.into( &ConfigData::outputFilename );
cli.bind( &ConfigData::reporterName )
cli["-r"]["--reporter"]
// .placeholder( "name[:filename]" )
.placeholder( "name" )
.describe( "reporter to use (defaults to console)" )
.shortOpt( "r")
.longOpt( "reporter" )
// .hint( "name[:filename]" );
.hint( "name" );
.into( &ConfigData::reporterName );
cli.bind( &ConfigData::name )
cli["-n"]["--name"]
.placeholder( "name" )
.describe( "suite name" )
.shortOpt( "n")
.longOpt( "name" )
.hint( "name" );
.into( &ConfigData::name );
cli.bind( &abortAfterFirst )
cli["-a"]["--abort"]
.describe( "abort at first failure" )
.shortOpt( "a")
.longOpt( "abort" );
.into( &abortAfterFirst );
cli.bind( &abortAfterX )
cli["-x"]["--abortx"]
.placeholder( "number of failures" )
.describe( "abort after x failures" )
.shortOpt( "x")
.longOpt( "abortx" )
.hint( "number of failures" );
.into( &abortAfterX );
cli.bind( &addWarning )
cli["-w"]["--warn"]
.placeholder( "warning name" )
.describe( "enable warnings" )
.shortOpt( "w")
.longOpt( "warn" )
.hint( "warning name" );
.into( &addWarning );
// cli.bind( &setVerbosity )
// - needs updating if reinstated
// cli.into( &setVerbosity )
// .describe( "level of verbosity (0=no output)" )
// .shortOpt( "v")
// .longOpt( "verbosity" )
// .hint( "level" );
// .placeholder( "level" );
cli.bind( &addTestOrTags )
cli[_]
.placeholder( "test name, pattern or tags" )
.describe( "which test or tests to use" )
.hint( "test name, pattern or tags" );
.into( &addTestOrTags );
cli.bind( &setShowDurations )
cli["-d"]["--durations"]
.placeholder( "yes/no" )
.describe( "show test durations" )
.shortOpt( "d")
.longOpt( "durations" )
.hint( "yes/no" );
.into( &setShowDurations );
cli.bind( &loadTestNamesFromFile )
cli["-f"]["--input-file"]
.placeholder( "filename" )
.describe( "load test names to run from a file" )
.shortOpt( "f")
.longOpt( "input-file" )
.hint( "filename" );
.into( &loadTestNamesFromFile );
// Less common commands which don't have a short form
cli.bind( &ConfigData::listTestNamesOnly )
cli["--list-test-names-only"]
.describe( "list all/matching test cases names only" )
.longOpt( "list-test-names-only" );
.into( &ConfigData::listTestNamesOnly );
cli.bind( &ConfigData::listReporters )
cli["--list-reporters"]
.describe( "list all reporters" )
.longOpt( "list-reporters" );
.into( &ConfigData::listReporters );
return cli;
}

View File

@ -7,12 +7,18 @@
*/
// Only use header guard if we are not using an outer namespace
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OUTER_NAMESPACE)
#ifndef STITCH_CLARA_OUTER_NAMESPACE
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
#ifndef STITCH_CLARA_OPEN_NAMESPACE
#define TWOBLUECUBES_CLARA_H_INCLUDED
#define STITCH_CLARA_OPEN_NAMESPACE
#define STITCH_CLARA_CLOSE_NAMESPACE
#else
#define STITCH_CLARA_CLOSE_NAMESPACE }
#endif
#define STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE Clara
#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
// ----------- #included from tbc_text_format.h -----------
@ -168,7 +174,7 @@ namespace Tbc {
// ----------- end of #include from tbc_text_format.h -----------
// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
#undef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
#include <map>
#include <algorithm>
@ -176,11 +182,20 @@ namespace Tbc {
#include <memory>
// Use optional outer namespace
#ifdef STITCH_CLARA_OUTER_NAMESPACE
namespace STITCH_CLARA_OUTER_NAMESPACE {
#ifdef STITCH_CLARA_OPEN_NAMESPACE
STITCH_CLARA_OPEN_NAMESPACE
#endif
namespace Clara {
struct UnpositionalTag {};
extern UnpositionalTag _;
#ifdef CLARA_CONFIG_MAIN
UnpositionalTag _;
#endif
namespace Detail {
#ifdef CLARA_CONSOLE_WIDTH
@ -189,7 +204,11 @@ namespace Clara {
const unsigned int consoleWidth = 80;
#endif
using namespace ::Clara::Tbc;
using namespace Tbc;
inline bool startsWith( std::string const& str, std::string const& prefix ) {
return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
}
template<typename T> struct RemoveConstRef{ typedef T type; };
template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
@ -240,6 +259,7 @@ namespace Clara {
template<typename ConfigT>
class BoundArgFunction {
public:
BoundArgFunction() : functionObj( NULL ) {}
BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj->clone() ) {}
BoundArgFunction& operator = ( BoundArgFunction const& other ) {
@ -422,6 +442,7 @@ namespace Clara {
class CommandLine {
struct Arg {
Arg() : position( -1 ) {}
Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ), position( -1 ) {}
bool hasShortName( std::string const& shortName ) const {
@ -437,7 +458,7 @@ namespace Clara {
return _longName == longName;
}
bool takesArg() const {
return !hint.empty();
return !placeholder.empty();
}
bool isFixedPositional() const {
return position != -1;
@ -454,7 +475,7 @@ namespace Clara {
}
void validate() const {
if( boundField.takesArg() && !takesArg() )
throw std::logic_error( "command line argument '" + dbgName() + "' must specify a hint" );
throw std::logic_error( "command line argument '" + dbgName() + "' must specify a placeholder" );
}
std::string commands() const {
std::ostringstream oss;
@ -472,8 +493,8 @@ namespace Clara {
oss << ", ";
oss << "--" << longName;
}
if( !hint.empty() )
oss << " <" << hint << ">";
if( !placeholder.empty() )
oss << " <" << placeholder << ">";
return oss.str();
}
@ -481,7 +502,7 @@ namespace Clara {
std::vector<std::string> shortNames;
std::string longName;
std::string description;
std::string hint;
std::string placeholder;
int position;
};
@ -492,14 +513,14 @@ namespace Clara {
typedef std::auto_ptr<Arg> ArgAutoPtr;
#endif
class ArgBinder {
class ArgBuilder {
public:
template<typename F>
ArgBinder( CommandLine* cl, F f )
: m_cl( cl ),
m_arg( Detail::makeBoundField( f ) )
ArgBuilder( CommandLine* cl )
: m_cl( cl )
{}
ArgBinder( ArgBinder& other )
ArgBuilder( ArgBuilder& other )
: m_cl( other.m_cl ),
m_arg( other.m_arg )
{
@ -507,7 +528,7 @@ namespace Clara {
}
// !TBD: Need to include workarounds to be able to declare this
// destructor as able to throw exceptions
~ArgBinder() /* noexcept(false) */ {
~ArgBuilder() /* noexcept(false) */ {
if( m_cl && !std::uncaught_exception() ) {
m_arg.validate();
if( m_arg.isFixedPositional() ) {
@ -524,30 +545,66 @@ namespace Clara {
m_cl->m_options.push_back( m_arg );
}
}
ArgBinder& shortOpt( std::string const& name ) {
m_arg.shortNames.push_back( name );
template<typename F>
void into( F f )
{
m_arg.boundField = Detail::makeBoundField( f );
}
friend void addOptName( ArgBuilder& builder, std::string const& optName )
{
if( optName.empty() )
return;
if( Detail::startsWith( optName, "--" ) ) {
if( !builder.m_arg.longName.empty() )
throw std::logic_error( "Only one long opt may be specified. '"
+ builder.m_arg.longName
+ "' already specified, now attempting to add '"
+ optName + "'" );
builder.m_arg.longName = optName.substr( 2 );
}
else if( Detail::startsWith( optName, "-" ) )
builder.m_arg.shortNames.push_back( optName.substr( 1 ) );
else
throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
}
friend void setPositionalArg( ArgBuilder& builder, int position )
{
builder.m_arg.position = position;
}
// Can only supply placeholder after [str] - if it takes an arg
ArgBuilder& placeholder( std::string const& placeholder ) {
m_arg.placeholder = placeholder;
return *this;
}
ArgBinder& longOpt( std::string const& name ) {
m_arg.longName = name;
return *this;
}
ArgBinder& describe( std::string const& description ) {
ArgBuilder& describe( std::string const& description ) {
m_arg.description = description;
return *this;
}
ArgBinder& hint( std::string const& hint ) {
m_arg.hint = hint;
return *this;
}
ArgBinder& position( int position ) {
m_arg.position = position;
ArgBuilder& detail( std::string const& ) {
// m_arg.description = description;
// !TBD
return *this;
}
private:
CommandLine* m_cl;
Arg m_arg;
};
class OptBuilder : public ArgBuilder {
public:
OptBuilder( CommandLine* cl ) : ArgBuilder( cl ) {}
OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
OptBuilder& operator[]( std::string const& optName ) {
addOptName( *this, optName );
return *this;
}
};
public:
@ -572,11 +629,25 @@ namespace Clara {
return *this;
}
template<typename F>
ArgBinder bind( F f ) {
ArgBinder binder( this, f );
return binder;
OptBuilder operator[]( std::string const& optName ) {
OptBuilder builder( this );
addOptName( builder, optName );
return builder;
}
ArgBuilder operator[]( int position ) {
ArgBuilder builder( this );
setPositionalArg( builder, position );
return builder;
}
// Invoke this with the _ instance
ArgBuilder operator[]( UnpositionalTag ) {
ArgBuilder builder( this );
return builder;
}
template<typename F>
void bindProcessName( F f ) {
m_boundProcessName = Detail::makeBoundField( f );
@ -619,9 +690,9 @@ namespace Clara {
os << " ";
typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
if( it != m_positionalArgs.end() )
os << "<" << it->second.hint << ">";
os << "<" << it->second.placeholder << ">";
else if( m_arg.get() )
os << "<" << m_arg->hint << ">";
os << "<" << m_arg->placeholder << ">";
else
throw std::logic_error( "non consecutive positional arguments with no floating args" );
}
@ -629,7 +700,7 @@ namespace Clara {
if( m_arg.get() ) {
if( m_highestSpecifiedArgPosition > 1 )
os << " ";
os << "[<" << m_arg->hint << "> ...]";
os << "[<" << m_arg->placeholder << "> ...]";
}
}
std::string argSynopsis() const {
@ -769,8 +840,10 @@ namespace Clara {
} // end namespace Clara
#ifdef STITCH_CLARA_OUTER_NAMESPACE
} // end outer namespace
#endif
STITCH_CLARA_CLOSE_NAMESPACE
#undef STITCH_CLARA_OPEN_NAMESPACE
#undef STITCH_CLARA_CLOSE_NAMESPACE
#endif // TWOBLUECUBES_CLARA_H_INCLUDED

View File

@ -1,192 +0,0 @@
/*
* Created by Phil on 22/10/2010.
* Copyright 2010 Two Blue Cubes Ltd
*
* 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)
*/
#ifdef __clang__
#pragma clang diagnostic ignored "-Wpadded"
#endif
#include "internal/clara.h" // This will does not declare Clara within the Catch namespace
#include "catch.hpp"
// Helper to deduce size from array literals and pass on to parser
template<size_t size, typename ConfigT>
std::vector<Clara::Parser::Token> parseInto( Clara::CommandLine<ConfigT>& cli, char const * (&argv)[size], ConfigT& config ) {
return cli.parseInto( size, argv, config );
}
struct TestOpt {
TestOpt() : number( 0 ), index( 0 ), flag( false ) {}
std::string processName;
std::string fileName;
int number;
int index;
bool flag;
std::string firstPos;
std::string secondPos;
std::string unpositional;
void setValidIndex( int i ) {
if( i < 0 || i > 10 )
throw std::domain_error( "index must be between 0 and 10" );
index = i;
}
};
struct TestOpt2 {
std::string description;
};
#ifdef CATCH_CONFIG_VARIADIC_MACROS
TEST_CASE( "cmdline" ) {
TestOpt config;
Clara::CommandLine<TestOpt> cli;
cli.bindProcessName( &TestOpt::processName );
cli.bind( &TestOpt::fileName )
.describe( "specifies output file" )
.shortOpt( "o" )
.longOpt( "output" )
.hint( "filename" );
SECTION( "process name" ) {
char const * argv[] = { "test", "-o filename.ext" };
parseInto( cli, argv, config );
CHECK( config.processName == "test" );
}
SECTION( "arg separated by spaces" ) {
char const * argv[] = { "test", "-o filename.ext" };
parseInto( cli, argv, config );
CHECK( config.fileName == "filename.ext" );
}
SECTION( "arg separated by colon" ) {
const char* argv[] = { "test", "-o:filename.ext" };
parseInto( cli, argv, config );
CHECK( config.fileName == "filename.ext" );
}
SECTION( "arg separated by =" ) {
const char* argv[] = { "test", "-o=filename.ext" };
parseInto( cli, argv, config );
CHECK( config.fileName == "filename.ext" );
}
SECTION( "long opt" ) {
const char* argv[] = { "test", "--output %stdout" };
parseInto( cli, argv, config );
CHECK( config.fileName == "%stdout" );
}
cli.bind( &TestOpt::number )
.shortOpt( "n" )
.hint( "an integral value" );
SECTION( "a number" ) {
const char* argv[] = { "test", "-n 42" };
parseInto( cli, argv, config );
CHECK( config.number == 42 );
}
SECTION( "not a number" ) {
const char* argv[] = { "test", "-n forty-two" };
CHECK_THROWS( parseInto( cli, argv, config ) );
CHECK( config.number == 0 );
}
SECTION( "two parsers" ) {
TestOpt config1;
TestOpt2 config2;
Clara::CommandLine<TestOpt2> cli2;
cli2.bind( &TestOpt2::description )
.describe( "description" )
.shortOpt( "d" )
.longOpt( "description" )
.hint( "some text" );
const char* argv[] = { "test", "-n 42", "-d some text" };
std::vector<Clara::Parser::Token> unusedTokens = parseInto( cli, argv, config1 );
CHECK( config1.number == 42 );
REQUIRE_FALSE( unusedTokens.empty() );
cli2.populate( unusedTokens, config2 );
CHECK( config2.description == "some text" );
}
SECTION( "methods" ) {
cli.bind( &TestOpt::setValidIndex )
.describe( "An index, which is an integer between 0 and 10, inclusive" )
.shortOpt( "i" )
.hint( "index" );
SECTION( "in range" ) {
const char* argv[] = { "test", "-i 3" };
parseInto( cli, argv, config );
REQUIRE( config.index == 3 );
}
SECTION( "out of range" ) {
const char* argv[] = { "test", "-i 42" };
REQUIRE_THROWS( parseInto( cli, argv, config ) );
}
}
SECTION( "flags" ) {
cli.bind( &TestOpt::flag )
.describe( "A flag" )
.shortOpt( "f" );
SECTION( "set" ) {
const char* argv[] = { "test", "-f" };
parseInto( cli, argv, config );
REQUIRE( config.flag );
}
SECTION( "not set" ) {
const char* argv[] = { "test" };
parseInto( cli, argv, config );
REQUIRE( config.flag == false );
}
}
SECTION( "positional" ) {
cli.bind( &TestOpt::secondPos )
.describe( "Second position" )
.hint( "second arg" )
.position( 2 );
cli.bind( &TestOpt::unpositional )
.hint( "any arg" )
.describe( "Unpositional" );
cli.bind( &TestOpt::firstPos )
.describe( "First position" )
.hint( "first arg" )
.position( 1 );
// std::cout << cli.usage( "testApp" ) << std::endl;
const char* argv[] = { "test", "-f", "1st", "-o", "filename", "2nd", "3rd" };
parseInto( cli, argv, config );
REQUIRE( config.firstPos == "1st" );
REQUIRE( config.secondPos == "2nd" );
REQUIRE( config.unpositional == "3rd" );
}
}
#endif

View File

@ -8,7 +8,6 @@
/* Begin PBXBuildFile section */
266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */; };
266E9AD617290E8E0061DAB2 /* CmdLineTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266E9AD417290E8E0061DAB2 /* CmdLineTests.cpp */; };
266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266ECD73170F3C620030D735 /* BDDTests.cpp */; };
26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; };
26948286179A9AB900ED166E /* SectionTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26948284179A9AB900ED166E /* SectionTrackerTests.cpp */; };
@ -68,7 +67,6 @@
263FD06117AF8DF200988A20 /* catch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_timer.h; sourceTree = "<group>"; };
266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VariadicMacrosTests.cpp; path = ../../../SelfTest/VariadicMacrosTests.cpp; sourceTree = "<group>"; };
266E9AD117230ACF0061DAB2 /* catch_text.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_text.hpp; sourceTree = "<group>"; };
266E9AD417290E8E0061DAB2 /* CmdLineTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CmdLineTests.cpp; path = ../../../SelfTest/CmdLineTests.cpp; sourceTree = "<group>"; };
266ECD73170F3C620030D735 /* BDDTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BDDTests.cpp; path = ../../../SelfTest/BDDTests.cpp; sourceTree = "<group>"; };
266ECD8C1713614B0030D735 /* catch_legacy_reporter_adapter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_legacy_reporter_adapter.hpp; sourceTree = "<group>"; };
266ECD8D1713614B0030D735 /* catch_legacy_reporter_adapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_legacy_reporter_adapter.h; sourceTree = "<group>"; };
@ -193,7 +191,6 @@
266E9AD317290E710061DAB2 /* Introspective Tests */ = {
isa = PBXGroup;
children = (
266E9AD417290E8E0061DAB2 /* CmdLineTests.cpp */,
26948284179A9AB900ED166E /* SectionTrackerTests.cpp */,
);
name = "Introspective Tests";
@ -535,7 +532,6 @@
26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */,
266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */,
266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */,
266E9AD617290E8E0061DAB2 /* CmdLineTests.cpp in Sources */,
26948286179A9AB900ED166E /* SectionTrackerTests.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -1,6 +1,6 @@
/*
* CATCH v1.0 build 27 (master branch)
* Generated: 2014-03-01 10:36:25.999888
* Generated: 2014-03-06 08:06:07.489513
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@ -3005,19 +3005,29 @@ namespace Catch {
// #included from: catch_clara.h
#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
// Use Catch's value for console width (store Clara's off to the side, if present)
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
#undef CLARA_CONFIG_CONSOLE_WIDTH
#endif
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
// Declare Clara inside the Catch namespace
#define STITCH_CLARA_OUTER_NAMESPACE Catch
#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
// #included from: clara.h
// Only use header guard if we are not using an outer namespace
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OUTER_NAMESPACE)
#ifndef STITCH_CLARA_OUTER_NAMESPACE
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
#ifndef STITCH_CLARA_OPEN_NAMESPACE
#define TWOBLUECUBES_CLARA_H_INCLUDED
#define STITCH_CLARA_OPEN_NAMESPACE
#define STITCH_CLARA_CLOSE_NAMESPACE
#else
#define STITCH_CLARA_CLOSE_NAMESPACE }
#endif
#define STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE Clara
#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
// ----------- #included from tbc_text_format.h -----------
@ -3166,7 +3176,7 @@ namespace Tbc {
// ----------- end of #include from tbc_text_format.h -----------
// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
#undef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
#include <map>
#include <algorithm>
@ -3174,11 +3184,20 @@ namespace Tbc {
#include <memory>
// Use optional outer namespace
#ifdef STITCH_CLARA_OUTER_NAMESPACE
namespace STITCH_CLARA_OUTER_NAMESPACE {
#ifdef STITCH_CLARA_OPEN_NAMESPACE
STITCH_CLARA_OPEN_NAMESPACE
#endif
namespace Clara {
struct UnpositionalTag {};
extern UnpositionalTag _;
#ifdef CLARA_CONFIG_MAIN
UnpositionalTag _;
#endif
namespace Detail {
#ifdef CLARA_CONSOLE_WIDTH
@ -3187,7 +3206,11 @@ namespace Clara {
const unsigned int consoleWidth = 80;
#endif
using namespace ::Clara::Tbc;
using namespace Tbc;
inline bool startsWith( std::string const& str, std::string const& prefix ) {
return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
}
template<typename T> struct RemoveConstRef{ typedef T type; };
template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
@ -3238,6 +3261,7 @@ namespace Clara {
template<typename ConfigT>
class BoundArgFunction {
public:
BoundArgFunction() : functionObj( NULL ) {}
BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj->clone() ) {}
BoundArgFunction& operator = ( BoundArgFunction const& other ) {
@ -3419,6 +3443,7 @@ namespace Clara {
class CommandLine {
struct Arg {
Arg() : position( -1 ) {}
Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ), position( -1 ) {}
bool hasShortName( std::string const& shortName ) const {
@ -3434,7 +3459,7 @@ namespace Clara {
return _longName == longName;
}
bool takesArg() const {
return !hint.empty();
return !placeholder.empty();
}
bool isFixedPositional() const {
return position != -1;
@ -3451,7 +3476,7 @@ namespace Clara {
}
void validate() const {
if( boundField.takesArg() && !takesArg() )
throw std::logic_error( "command line argument '" + dbgName() + "' must specify a hint" );
throw std::logic_error( "command line argument '" + dbgName() + "' must specify a placeholder" );
}
std::string commands() const {
std::ostringstream oss;
@ -3469,8 +3494,8 @@ namespace Clara {
oss << ", ";
oss << "--" << longName;
}
if( !hint.empty() )
oss << " <" << hint << ">";
if( !placeholder.empty() )
oss << " <" << placeholder << ">";
return oss.str();
}
@ -3478,7 +3503,7 @@ namespace Clara {
std::vector<std::string> shortNames;
std::string longName;
std::string description;
std::string hint;
std::string placeholder;
int position;
};
@ -3489,14 +3514,13 @@ namespace Clara {
typedef std::auto_ptr<Arg> ArgAutoPtr;
#endif
class ArgBinder {
class ArgBuilder {
public:
template<typename F>
ArgBinder( CommandLine* cl, F f )
: m_cl( cl ),
m_arg( Detail::makeBoundField( f ) )
ArgBuilder( CommandLine* cl )
: m_cl( cl )
{}
ArgBinder( ArgBinder& other )
ArgBuilder( ArgBuilder& other )
: m_cl( other.m_cl ),
m_arg( other.m_arg )
{
@ -3504,7 +3528,7 @@ namespace Clara {
}
// !TBD: Need to include workarounds to be able to declare this
// destructor as able to throw exceptions
~ArgBinder() /* noexcept(false) */ {
~ArgBuilder() /* noexcept(false) */ {
if( m_cl && !std::uncaught_exception() ) {
m_arg.validate();
if( m_arg.isFixedPositional() ) {
@ -3521,30 +3545,65 @@ namespace Clara {
m_cl->m_options.push_back( m_arg );
}
}
ArgBinder& shortOpt( std::string const& name ) {
m_arg.shortNames.push_back( name );
template<typename F>
void into( F f )
{
m_arg.boundField = Detail::makeBoundField( f );
}
friend void addOptName( ArgBuilder& builder, std::string const& optName )
{
if( optName.empty() )
return;
if( Detail::startsWith( optName, "--" ) ) {
if( !builder.m_arg.longName.empty() )
throw std::logic_error( "Only one long opt may be specified. '"
+ builder.m_arg.longName
+ "' already specified, now attempting to add '"
+ optName + "'" );
builder.m_arg.longName = optName.substr( 2 );
}
else if( Detail::startsWith( optName, "-" ) )
builder.m_arg.shortNames.push_back( optName.substr( 1 ) );
else
throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
}
friend void setPositionalArg( ArgBuilder& builder, int position )
{
builder.m_arg.position = position;
}
// Can only supply placeholder after [str] - if it takes an arg
ArgBuilder& placeholder( std::string const& placeholder ) {
m_arg.placeholder = placeholder;
return *this;
}
ArgBinder& longOpt( std::string const& name ) {
m_arg.longName = name;
return *this;
}
ArgBinder& describe( std::string const& description ) {
ArgBuilder& describe( std::string const& description ) {
m_arg.description = description;
return *this;
}
ArgBinder& hint( std::string const& hint ) {
m_arg.hint = hint;
return *this;
}
ArgBinder& position( int position ) {
m_arg.position = position;
ArgBuilder& detail( std::string const& ) {
// m_arg.description = description;
// !TBD
return *this;
}
private:
CommandLine* m_cl;
Arg m_arg;
};
class OptBuilder : public ArgBuilder {
public:
OptBuilder( CommandLine* cl ) : ArgBuilder( cl ) {}
OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
OptBuilder& operator[]( std::string const& optName ) {
addOptName( *this, optName );
return *this;
}
};
public:
@ -3569,11 +3628,24 @@ namespace Clara {
return *this;
}
template<typename F>
ArgBinder bind( F f ) {
ArgBinder binder( this, f );
return binder;
OptBuilder operator[]( std::string const& optName ) {
OptBuilder builder( this );
addOptName( builder, optName );
return builder;
}
ArgBuilder operator[]( int position ) {
ArgBuilder builder( this );
setPositionalArg( builder, position );
return builder;
}
// Invoke this with the _ instance
ArgBuilder operator[]( UnpositionalTag ) {
ArgBuilder builder( this );
return builder;
}
template<typename F>
void bindProcessName( F f ) {
m_boundProcessName = Detail::makeBoundField( f );
@ -3616,9 +3688,9 @@ namespace Clara {
os << " ";
typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
if( it != m_positionalArgs.end() )
os << "<" << it->second.hint << ">";
os << "<" << it->second.placeholder << ">";
else if( m_arg.get() )
os << "<" << m_arg->hint << ">";
os << "<" << m_arg->placeholder << ">";
else
throw std::logic_error( "non consecutive positional arguments with no floating args" );
}
@ -3626,7 +3698,7 @@ namespace Clara {
if( m_arg.get() ) {
if( m_highestSpecifiedArgPosition > 1 )
os << " ";
os << "[<" << m_arg->hint << "> ...]";
os << "[<" << m_arg->placeholder << "> ...]";
}
}
std::string argSynopsis() const {
@ -3766,12 +3838,18 @@ namespace Clara {
} // end namespace Clara
#ifdef STITCH_CLARA_OUTER_NAMESPACE
} // end outer namespace
#endif
STITCH_CLARA_CLOSE_NAMESPACE
#undef STITCH_CLARA_OPEN_NAMESPACE
#undef STITCH_CLARA_CLOSE_NAMESPACE
#endif // TWOBLUECUBES_CLARA_H_INCLUDED
#undef STITCH_CLARA_OUTER_NAMESPACE
#undef STITCH_CLARA_OPEN_NAMESPACE
// Restore Clara's value for console width, if present
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#endif
#include <fstream>
@ -3816,107 +3894,95 @@ namespace Catch {
inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
Clara::CommandLine<ConfigData> cli;
using namespace Clara;
CommandLine<ConfigData> cli;
cli.bindProcessName( &ConfigData::processName );
cli.bind( &ConfigData::showHelp )
cli["-?"]["-h"]["--help"]
.describe( "display usage information" )
.shortOpt( "?")
.shortOpt( "h")
.longOpt( "help" );
.into( &ConfigData::showHelp );
cli.bind( &ConfigData::listTests )
cli["-l"]["--list-tests"]
.describe( "list all/matching test cases" )
.shortOpt( "l")
.longOpt( "list-tests" );
.into( &ConfigData::listTests );
cli.bind( &ConfigData::listTags )
cli["-t"]["--list-tags"]
.describe( "list all/matching tags" )
.shortOpt( "t")
.longOpt( "list-tags" );
.into( &ConfigData::listTags );
cli.bind( &ConfigData::showSuccessfulTests )
cli["-s"]["--success"]
.describe( "include successful tests in output" )
.shortOpt( "s")
.longOpt( "success" );
.into( &ConfigData::showSuccessfulTests );
cli.bind( &ConfigData::shouldDebugBreak )
cli["-b"]["--break"]
.describe( "break into debugger on failure" )
.shortOpt( "b")
.longOpt( "break" );
.into( &ConfigData::shouldDebugBreak );
cli.bind( &ConfigData::noThrow )
cli["-e"]["--nothrow"]
.describe( "skip exception tests" )
.shortOpt( "e")
.longOpt( "nothrow" );
.into( &ConfigData::noThrow );
cli.bind( &ConfigData::outputFilename )
cli["-o"]["--out"]
.placeholder( "filename" )
.describe( "output filename" )
.shortOpt( "o")
.longOpt( "out" )
.hint( "filename" );
.into( &ConfigData::outputFilename );
cli.bind( &ConfigData::reporterName )
cli["-r"]["--reporter"]
// .placeholder( "name[:filename]" )
.placeholder( "name" )
.describe( "reporter to use (defaults to console)" )
.shortOpt( "r")
.longOpt( "reporter" )
// .hint( "name[:filename]" );
.hint( "name" );
.into( &ConfigData::reporterName );
cli.bind( &ConfigData::name )
cli["-n"]["--name"]
.placeholder( "name" )
.describe( "suite name" )
.shortOpt( "n")
.longOpt( "name" )
.hint( "name" );
.into( &ConfigData::name );
cli.bind( &abortAfterFirst )
cli["-a"]["--abort"]
.describe( "abort at first failure" )
.shortOpt( "a")
.longOpt( "abort" );
.into( &abortAfterFirst );
cli.bind( &abortAfterX )
cli["-x"]["--abortx"]
.placeholder( "number of failures" )
.describe( "abort after x failures" )
.shortOpt( "x")
.longOpt( "abortx" )
.hint( "number of failures" );
.into( &abortAfterX );
cli.bind( &addWarning )
cli["-w"]["--warn"]
.placeholder( "warning name" )
.describe( "enable warnings" )
.shortOpt( "w")
.longOpt( "warn" )
.hint( "warning name" );
.into( &addWarning );
// cli.bind( &setVerbosity )
// - needs updating if reinstated
// cli.into( &setVerbosity )
// .describe( "level of verbosity (0=no output)" )
// .shortOpt( "v")
// .longOpt( "verbosity" )
// .hint( "level" );
// .placeholder( "level" );
cli.bind( &addTestOrTags )
cli[_]
.placeholder( "test name, pattern or tags" )
.describe( "which test or tests to use" )
.hint( "test name, pattern or tags" );
.into( &addTestOrTags );
cli.bind( &setShowDurations )
cli["-d"]["--durations"]
.placeholder( "yes/no" )
.describe( "show test durations" )
.shortOpt( "d")
.longOpt( "durations" )
.hint( "yes/no" );
.into( &setShowDurations );
cli.bind( &loadTestNamesFromFile )
cli["-f"]["--input-file"]
.placeholder( "filename" )
.describe( "load test names to run from a file" )
.shortOpt( "f")
.longOpt( "input-file" )
.hint( "filename" );
.into( &loadTestNamesFromFile );
// Less common commands which don't have a short form
cli.bind( &ConfigData::listTestNamesOnly )
cli["--list-test-names-only"]
.describe( "list all/matching test cases names only" )
.longOpt( "list-test-names-only" );
.into( &ConfigData::listTestNamesOnly );
cli.bind( &ConfigData::listReporters )
cli["--list-reporters"]
.describe( "list all reporters" )
.longOpt( "list-reporters" );
.into( &ConfigData::listReporters );
return cli;
}