Added --use-colour option to give finer control over colourisation.

--force-colour is still present but deprecated (will remove in v2)
This commit is contained in:
Phil Nash 2016-02-24 18:51:01 +00:00
parent dce2154474
commit 8ccb18daa9
6 changed files with 86 additions and 24 deletions

View File

@ -62,6 +62,21 @@ namespace Catch {
? ShowDurations::Always ? ShowDurations::Always
: ShowDurations::Never; : ShowDurations::Never;
} }
inline void setUseColour( ConfigData& config, std::string const& value ) {
std::string mode = toLower( value );
if( mode == "yes" )
config.useColour = UseColour::Yes;
else if( mode == "no" )
config.useColour = UseColour::No;
else if( mode == "auto" )
config.useColour = UseColour::Auto;
else
throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
}
inline void forceColour( ConfigData& config ) {
config.useColour = UseColour::Yes;
}
inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
std::ifstream f( _filename.c_str() ); std::ifstream f( _filename.c_str() );
if( !f.is_open() ) if( !f.is_open() )
@ -148,7 +163,7 @@ namespace Catch {
cli["-d"]["--durations"] cli["-d"]["--durations"]
.describe( "show test durations" ) .describe( "show test durations" )
.bind( &setShowDurations, "yes/no" ); .bind( &setShowDurations, "yes|no" );
cli["-f"]["--input-file"] cli["-f"]["--input-file"]
.describe( "load test names to run from a file" ) .describe( "load test names to run from a file" )
@ -176,8 +191,12 @@ namespace Catch {
.bind( &setRngSeed, "'time'|number" ); .bind( &setRngSeed, "'time'|number" );
cli["--force-colour"] cli["--force-colour"]
.describe( "force colourised output" ) .describe( "force colourised output (deprecated)" )
.bind( &ConfigData::forceColour ); .bind( &forceColour );
cli["--use-colour"]
.describe( "should output be colourised" )
.bind( &setUseColour, "yes|no" );
return cli; return cli;
} }

View File

@ -37,14 +37,14 @@ namespace Catch {
noThrow( false ), noThrow( false ),
showHelp( false ), showHelp( false ),
showInvisibles( false ), showInvisibles( false ),
forceColour( false ),
filenamesAsTags( false ), filenamesAsTags( false ),
abortAfter( -1 ), abortAfter( -1 ),
rngSeed( 0 ), rngSeed( 0 ),
verbosity( Verbosity::Normal ), verbosity( Verbosity::Normal ),
warnings( WarnAbout::Nothing ), warnings( WarnAbout::Nothing ),
showDurations( ShowDurations::DefaultForReporter ), showDurations( ShowDurations::DefaultForReporter ),
runOrder( RunTests::InDeclarationOrder ) runOrder( RunTests::InDeclarationOrder ),
useColour( UseColour::Auto )
{} {}
bool listTests; bool listTests;
@ -57,7 +57,6 @@ namespace Catch {
bool noThrow; bool noThrow;
bool showHelp; bool showHelp;
bool showInvisibles; bool showInvisibles;
bool forceColour;
bool filenamesAsTags; bool filenamesAsTags;
int abortAfter; int abortAfter;
@ -67,6 +66,7 @@ namespace Catch {
WarnAbout::What warnings; WarnAbout::What warnings;
ShowDurations::OrNot showDurations; ShowDurations::OrNot showDurations;
RunTests::InWhatOrder runOrder; RunTests::InWhatOrder runOrder;
UseColour::YesOrNo useColour;
std::string outputFilename; std::string outputFilename;
std::string name; std::string name;
@ -133,7 +133,7 @@ namespace Catch {
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; } virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
virtual unsigned int rngSeed() const { return m_data.rngSeed; } virtual unsigned int rngSeed() const { return m_data.rngSeed; }
virtual bool forceColour() const { return m_data.forceColour; } virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
private: private:

View File

@ -95,7 +95,18 @@ namespace {
IColourImpl* platformColourInstance() { IColourImpl* platformColourInstance() {
static Win32ColourImpl s_instance; static Win32ColourImpl s_instance;
return &s_instance;
Ptr<IConfig const> config = getCurrentContext().getConfig();
UseColour::YesOrNo colourMode = config
? config->useColour()
: UseColour::Auto;
if( colourMode == UseColour::Auto )
colourMode = !isDebuggerActive()
? UseColour::Yes
: UseColour::No;
return colourMode == UseColour::Yes
? &s_instance
: NoColourImpl::instance();
} }
} // end anon namespace } // end anon namespace
@ -146,7 +157,14 @@ namespace {
IColourImpl* platformColourInstance() { IColourImpl* platformColourInstance() {
Ptr<IConfig const> config = getCurrentContext().getConfig(); Ptr<IConfig const> config = getCurrentContext().getConfig();
return (config && config->forceColour()) || isatty(STDOUT_FILENO) UseColour::YesOrNo colourMode = config
? config->useColour()
: UseColour::Auto;
if( colourMode == UseColour::Auto )
colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
? UseColour::Yes
: UseColour::No;
return colourMode == UseColour::Yes
? PosixColourImpl::instance() ? PosixColourImpl::instance()
: NoColourImpl::instance(); : NoColourImpl::instance();
} }
@ -171,9 +189,7 @@ namespace Catch {
Colour::~Colour(){ if( !m_moved ) use( None ); } Colour::~Colour(){ if( !m_moved ) use( None ); }
void Colour::use( Code _colourCode ) { void Colour::use( Code _colourCode ) {
static IColourImpl* impl = isDebuggerActive() static IColourImpl* impl = platformColourInstance();
? NoColourImpl::instance()
: platformColourInstance();
impl->use( _colourCode ); impl->use( _colourCode );
} }

View File

@ -37,6 +37,11 @@ namespace Catch {
InLexicographicalOrder, InLexicographicalOrder,
InRandomOrder InRandomOrder
}; }; }; };
struct UseColour { enum YesOrNo {
Auto,
Yes,
No
}; };
class TestSpec; class TestSpec;
@ -56,7 +61,7 @@ namespace Catch {
virtual TestSpec const& testSpec() const = 0; virtual TestSpec const& testSpec() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0; virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0; virtual unsigned int rngSeed() const = 0;
virtual bool forceColour() const = 0; virtual UseColour::YesOrNo useColour() const = 0;
}; };
} }

View File

@ -195,19 +195,41 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
} }
} }
SECTION( "force-colour", "") { SECTION( "use-colour", "") {
SECTION( "--force-colour", "" ) {
const char* argv[] = { "test", "--force-colour" }; using Catch::UseColour;
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
SECTION( "without option", "" ) {
REQUIRE( config.forceColour );
}
SECTION( "without --force-colour", "" ) {
const char* argv[] = { "test" }; const char* argv[] = { "test" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) ); CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.useColour == UseColour::Auto );
}
REQUIRE( !config.forceColour ); SECTION( "auto", "" ) {
const char* argv[] = { "test", "--use-colour", "auto" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.useColour == UseColour::Auto );
}
SECTION( "yes", "" ) {
const char* argv[] = { "test", "--use-colour", "yes" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.useColour == UseColour::Yes );
}
SECTION( "no", "" ) {
const char* argv[] = { "test", "--use-colour", "no" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.useColour == UseColour::No );
}
SECTION( "error", "" ) {
const char* argv[] = { "test", "--use-colour", "wrong" };
REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) );
} }
} }
} }

View File

@ -93,7 +93,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\SelfTest\ApproxTests.cpp" /> <ClCompile Include="..\..\..\SelfTest\ApproxTests.cpp" />
<ClCompile Include="..\..\..\SelfTest\BDDTests.cpp" /> <ClCompile Include="..\..\..\SelfTest\BDDTests.cpp" />
<ClCompile Include="..\..\..\SelfTest\SectionTrackerTests.cpp" /> <ClCompile Include="..\..\..\SelfTest\PartTrackerTests.cpp" />
<ClCompile Include="..\..\..\SelfTest\TestMain.cpp" /> <ClCompile Include="..\..\..\SelfTest\TestMain.cpp" />
<ClCompile Include="..\..\..\SelfTest\ClassTests.cpp" /> <ClCompile Include="..\..\..\SelfTest\ClassTests.cpp" />
<ClCompile Include="..\..\..\SelfTest\ConditionTests.cpp" /> <ClCompile Include="..\..\..\SelfTest\ConditionTests.cpp" />