Catch VS integration Part 2 - modify version, allow multiple includes

This commit is contained in:
Malcolm Noyes 2013-11-14 19:49:49 +00:00
parent e9a2230ad8
commit 73f7f0ad1b
18 changed files with 145 additions and 75 deletions

View File

@ -17,9 +17,22 @@
#pragma clang diagnostic ignored "-Wpadded"
#endif
#if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR
#define INTERNAL_CATCH_VS_MANAGED
#else
#if defined(_WINDLL)
// _WINDLL seems to be the only thing we can check for the existence of a native DLL.
// It's possible that this is not enough for someone so allow it to be overridden...
#if !defined( CATCH_CONFIG_MAIN ) && !defined( CATCH_CONFIG_RUNNER )
#define INTERNAL_CATCH_VS_NATIVE
#endif
#endif
#endif // detect CLR
#include "internal/catch_notimplemented_exception.h"
#include "internal/catch_context.h"
#include "internal/catch_test_registry.hpp"
#include "internal/catch_capture.hpp"
#include "internal/catch_section.hpp"
#include "internal/catch_generators.hpp"
@ -33,10 +46,24 @@
#include "internal/catch_test_case_info.h"
#include "internal/catch_interfaces_runner.h"
#ifdef __OBJC__
#include "internal/catch_objc.hpp"
#endif
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
#define INTERNAL_CATCH_INLINE inline
#ifdef INTERNAL_CATCH_VS_MANAGED
#include "internal/catch_vs_managed_impl.hpp"
#else // INTERNAL_CATCH_VS_MANAGED
#ifdef INTERNAL_CATCH_VS_NATIVE
#include "internal/catch_vs_native_impl.hpp"
#endif // INTERNAL_CATCH_VS_NATIVE
#endif // INTERNAL_CATCH_VS_MANAGED
#else
#include "internal/catch_test_registry.hpp"
#if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER )
#define INTERNAL_CATCH_INLINE
#include "internal/catch_impl.hpp"
@ -46,6 +73,8 @@
#include "internal/catch_default_main.hpp"
#endif
#endif // INTERNAL_CATCH_VS_MANAGED or INTERNAL_CATCH_VS_NATIVE defined
//////
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_

View File

@ -129,11 +129,11 @@ namespace Catch {
}
void showHelp( std::string const& processName ) {
std::cout << "\nCatch v" << libraryVersion.majorVersion << "."
<< libraryVersion.minorVersion << " build "
<< libraryVersion.buildNumber;
if( libraryVersion.branchName != "master" )
std::cout << " (" << libraryVersion.branchName << " branch)";
std::cout << "\nCatch v" << libraryVersion::value.majorVersion << "."
<< libraryVersion::value.minorVersion << " build "
<< libraryVersion::value.buildNumber;
if( libraryVersion::value.branchName != "master" )
std::cout << " (" << libraryVersion::value.branchName << " branch)";
std::cout << "\n";
m_cli.usage( std::cout, processName );

View File

@ -13,7 +13,7 @@
namespace Catch {
AssertionInfo::AssertionInfo( std::string const& _macroName,
INTERNAL_CATCH_INLINE AssertionInfo::AssertionInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition )
@ -23,66 +23,66 @@ namespace Catch {
resultDisposition( _resultDisposition )
{}
AssertionResult::AssertionResult() {}
INTERNAL_CATCH_INLINE AssertionResult::AssertionResult() {}
AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
INTERNAL_CATCH_INLINE AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
: m_info( info ),
m_resultData( data )
{}
AssertionResult::~AssertionResult() {}
INTERNAL_CATCH_INLINE AssertionResult::~AssertionResult() {}
// Result was a success
bool AssertionResult::succeeded() const {
INTERNAL_CATCH_INLINE bool AssertionResult::succeeded() const {
return Catch::isOk( m_resultData.resultType );
}
// Result was a success, or failure is suppressed
bool AssertionResult::isOk() const {
INTERNAL_CATCH_INLINE bool AssertionResult::isOk() const {
return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
}
ResultWas::OfType AssertionResult::getResultType() const {
INTERNAL_CATCH_INLINE ResultWas::OfType AssertionResult::getResultType() const {
return m_resultData.resultType;
}
bool AssertionResult::hasExpression() const {
INTERNAL_CATCH_INLINE bool AssertionResult::hasExpression() const {
return !m_info.capturedExpression.empty();
}
bool AssertionResult::hasMessage() const {
INTERNAL_CATCH_INLINE bool AssertionResult::hasMessage() const {
return !m_resultData.message.empty();
}
std::string AssertionResult::getExpression() const {
INTERNAL_CATCH_INLINE std::string AssertionResult::getExpression() const {
if( shouldNegate( m_info.resultDisposition ) )
return "!" + m_info.capturedExpression;
else
return m_info.capturedExpression;
}
std::string AssertionResult::getExpressionInMacro() const {
INTERNAL_CATCH_INLINE std::string AssertionResult::getExpressionInMacro() const {
if( m_info.macroName.empty() )
return m_info.capturedExpression;
else
return m_info.macroName + "( " + m_info.capturedExpression + " )";
}
bool AssertionResult::hasExpandedExpression() const {
INTERNAL_CATCH_INLINE bool AssertionResult::hasExpandedExpression() const {
return hasExpression() && getExpandedExpression() != getExpression();
}
std::string AssertionResult::getExpandedExpression() const {
INTERNAL_CATCH_INLINE std::string AssertionResult::getExpandedExpression() const {
return m_resultData.reconstructedExpression;
}
std::string AssertionResult::getMessage() const {
INTERNAL_CATCH_INLINE std::string AssertionResult::getMessage() const {
return m_resultData.message;
}
SourceLineInfo AssertionResult::getSourceInfo() const {
INTERNAL_CATCH_INLINE SourceLineInfo AssertionResult::getSourceInfo() const {
return m_info.lineInfo;
}
std::string AssertionResult::getTestMacroName() const {
INTERNAL_CATCH_INLINE std::string AssertionResult::getTestMacroName() const {
return m_info.macroName;
}

View File

@ -86,16 +86,16 @@ namespace Catch {
namespace {
Context* currentContext = NULL;
}
IMutableContext& getCurrentMutableContext() {
INTERNAL_CATCH_INLINE IMutableContext& getCurrentMutableContext() {
if( !currentContext )
currentContext = new Context();
return *currentContext;
}
IContext& getCurrentContext() {
INTERNAL_CATCH_INLINE IContext& getCurrentContext() {
return getCurrentMutableContext();
}
Stream createStream( std::string const& streamName ) {
INTERNAL_CATCH_INLINE Stream createStream( std::string const& 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 );
@ -103,7 +103,7 @@ namespace Catch {
throw std::domain_error( "Unknown stream: " + streamName );
}
void cleanUpContext() {
INTERNAL_CATCH_INLINE void cleanUpContext() {
delete currentContext;
currentContext = NULL;
}

View File

@ -14,47 +14,47 @@
namespace Catch {
ExpressionResultBuilder::ExpressionResultBuilder( ResultWas::OfType resultType ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder::ExpressionResultBuilder( ResultWas::OfType resultType ) {
m_data.resultType = resultType;
}
ExpressionResultBuilder::ExpressionResultBuilder( ExpressionResultBuilder const& other )
INTERNAL_CATCH_INLINE ExpressionResultBuilder::ExpressionResultBuilder( ExpressionResultBuilder const& other )
: m_data( other.m_data ),
m_exprComponents( other.m_exprComponents )
{
m_stream << other.m_stream.str();
}
ExpressionResultBuilder& ExpressionResultBuilder::operator=(ExpressionResultBuilder const& other ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::operator=(ExpressionResultBuilder const& other ) {
m_data = other.m_data;
m_exprComponents = other.m_exprComponents;
m_stream.str("");
m_stream << other.m_stream.str();
return *this;
}
ExpressionResultBuilder& ExpressionResultBuilder::setResultType( ResultWas::OfType result ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::setResultType( ResultWas::OfType result ) {
m_data.resultType = result;
return *this;
}
ExpressionResultBuilder& ExpressionResultBuilder::setResultType( bool result ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::setResultType( bool result ) {
m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
return *this;
}
ExpressionResultBuilder& ExpressionResultBuilder::endExpression( ResultDisposition::Flags resultDisposition ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::endExpression( ResultDisposition::Flags resultDisposition ) {
m_exprComponents.shouldNegate = shouldNegate( resultDisposition );
return *this;
}
ExpressionResultBuilder& ExpressionResultBuilder::setLhs( std::string const& lhs ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::setLhs( std::string const& lhs ) {
m_exprComponents.lhs = lhs;
return *this;
}
ExpressionResultBuilder& ExpressionResultBuilder::setRhs( std::string const& rhs ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::setRhs( std::string const& rhs ) {
m_exprComponents.rhs = rhs;
return *this;
}
ExpressionResultBuilder& ExpressionResultBuilder::setOp( std::string const& op ) {
INTERNAL_CATCH_INLINE ExpressionResultBuilder& ExpressionResultBuilder::setOp( std::string const& op ) {
m_exprComponents.op = op;
return *this;
}
AssertionResult ExpressionResultBuilder::buildResult( AssertionInfo const& info ) const
INTERNAL_CATCH_INLINE AssertionResult ExpressionResultBuilder::buildResult( AssertionInfo const& info ) const
{
assert( m_data.resultType != ResultWas::Unknown );
@ -76,7 +76,7 @@ namespace Catch {
}
return AssertionResult( info, data );
}
std::string ExpressionResultBuilder::reconstructExpression( AssertionInfo const& info ) const {
INTERNAL_CATCH_INLINE std::string ExpressionResultBuilder::reconstructExpression( AssertionInfo const& info ) const {
if( m_exprComponents.op == "" )
return m_exprComponents.lhs.empty() ? info.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
else if( m_exprComponents.op == "matches" )

View File

@ -76,7 +76,7 @@ namespace Catch {
std::vector<IGeneratorInfo*> m_generatorsInOrder;
};
IGeneratorsForTest* createGeneratorsForTest()
INTERNAL_CATCH_INLINE IGeneratorsForTest* createGeneratorsForTest()
{
return new GeneratorsForTest();
}

View File

@ -13,7 +13,7 @@
namespace Catch {
NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
INTERNAL_CATCH_INLINE NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
: m_lineInfo( lineInfo ) {
std::ostringstream oss;
oss << lineInfo << ": function ";
@ -21,7 +21,7 @@ namespace Catch {
m_what = oss.str();
}
const char* NotImplementedException::what() const throw() {
INTERNAL_CATCH_INLINE const char* NotImplementedException::what() const throw() {
return m_what.c_str();
}

View File

@ -12,7 +12,6 @@
#include "catch_interfaces_reporter.h"
#include "catch_interfaces_exception.h"
#include "catch_config.hpp"
#include "catch_test_registry.hpp"
#include "catch_test_case_info.h"
#include "catch_capture.hpp"
#include "catch_totals.hpp"

View File

@ -15,7 +15,7 @@
namespace Catch {
TestCase makeTestCase( ITestCase* _testCase,
INTERNAL_CATCH_INLINE TestCase makeTestCase( ITestCase* _testCase,
std::string const& _className,
std::string const& _name,
std::string const& _descOrTags,
@ -32,7 +32,7 @@ namespace Catch {
return TestCase( _testCase, info );
}
TestCaseInfo::TestCaseInfo( std::string const& _name,
INTERNAL_CATCH_INLINE TestCaseInfo::TestCaseInfo( std::string const& _name,
std::string const& _className,
std::string const& _description,
std::set<std::string> const& _tags,
@ -51,7 +51,7 @@ namespace Catch {
tagsAsString = oss.str();
}
TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
INTERNAL_CATCH_INLINE TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
: name( other.name ),
className( other.className ),
description( other.description ),
@ -61,40 +61,40 @@ namespace Catch {
isHidden( other.isHidden )
{}
TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
INTERNAL_CATCH_INLINE TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
TestCase::TestCase( TestCase const& other )
INTERNAL_CATCH_INLINE TestCase::TestCase( TestCase const& other )
: TestCaseInfo( other ),
test( other.test )
{}
TestCase TestCase::withName( std::string const& _newName ) const {
INTERNAL_CATCH_INLINE TestCase TestCase::withName( std::string const& _newName ) const {
TestCase other( *this );
other.name = _newName;
return other;
}
void TestCase::invoke() const {
INTERNAL_CATCH_INLINE void TestCase::invoke() const {
test->invoke();
}
bool TestCase::isHidden() const {
INTERNAL_CATCH_INLINE bool TestCase::isHidden() const {
return TestCaseInfo::isHidden;
}
bool TestCase::hasTag( std::string const& tag ) const {
INTERNAL_CATCH_INLINE bool TestCase::hasTag( std::string const& tag ) const {
return tags.find( toLower( tag ) ) != tags.end();
}
bool TestCase::matchesTags( std::string const& tagPattern ) const {
INTERNAL_CATCH_INLINE bool TestCase::matchesTags( std::string const& tagPattern ) const {
TagExpression exp;
TagExpressionParser( exp ).parse( tagPattern );
return exp.matches( tags );
}
std::set<std::string> const& TestCase::getTags() const {
INTERNAL_CATCH_INLINE std::set<std::string> const& TestCase::getTags() const {
return tags;
}
void TestCase::swap( TestCase& other ) {
INTERNAL_CATCH_INLINE void TestCase::swap( TestCase& other ) {
test.swap( other.test );
className.swap( other.className );
name.swap( other.name );
@ -102,22 +102,22 @@ namespace Catch {
std::swap( lineInfo, other.lineInfo );
}
bool TestCase::operator == ( TestCase const& other ) const {
INTERNAL_CATCH_INLINE bool TestCase::operator == ( TestCase const& other ) const {
return test.get() == other.test.get() &&
name == other.name &&
className == other.className;
}
bool TestCase::operator < ( TestCase const& other ) const {
INTERNAL_CATCH_INLINE bool TestCase::operator < ( TestCase const& other ) const {
return name < other.name;
}
TestCase& TestCase::operator = ( TestCase const& other ) {
INTERNAL_CATCH_INLINE TestCase& TestCase::operator = ( TestCase const& other ) {
TestCase temp( other );
swap( temp );
return *this;
}
TestCaseInfo const& TestCase::getTestCaseInfo() const
INTERNAL_CATCH_INLINE TestCaseInfo const& TestCase::getTestCaseInfo() const
{
return *this;
}

View File

@ -13,7 +13,7 @@
namespace Catch {
Text::Text( std::string const& _str, TextAttributes const& _attr )
INTERNAL_CATCH_INLINE Text::Text( std::string const& _str, TextAttributes const& _attr )
: attr( _attr )
{
std::string wrappableChars = " [({.,/|\\-";
@ -69,18 +69,18 @@ namespace Catch {
}
}
void Text::spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
INTERNAL_CATCH_INLINE void Text::spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
_remainder = _remainder.substr( _pos );
}
std::string Text::toString() const {
INTERNAL_CATCH_INLINE std::string Text::toString() const {
std::ostringstream oss;
oss << *this;
return oss.str();
}
std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
INTERNAL_CATCH_INLINE std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
it != itEnd; ++it ) {
if( it != _text.begin() )

View File

@ -24,7 +24,7 @@ namespace Catch {
namespace {
#ifdef CATCH_PLATFORM_WINDOWS
uint64_t getCurrentTicks() {
INTERNAL_CATCH_INLINE uint64_t getCurrentTicks() {
static uint64_t hz=0, hzo=0;
if (!hz) {
QueryPerformanceFrequency((LARGE_INTEGER*)&hz);
@ -35,7 +35,7 @@ namespace Catch {
return ((t-hzo)*1000000)/hz;
}
#else
uint64_t getCurrentTicks() {
INTERNAL_CATCH_INLINE uint64_t getCurrentTicks() {
timeval t;
gettimeofday(&t,NULL);
return (uint64_t)t.tv_sec * 1000000ull + (uint64_t)t.tv_usec;
@ -43,16 +43,16 @@ namespace Catch {
#endif
}
void Timer::start() {
INTERNAL_CATCH_INLINE void Timer::start() {
m_ticks = getCurrentTicks();
}
unsigned int Timer::getElapsedNanoseconds() const {
INTERNAL_CATCH_INLINE unsigned int Timer::getElapsedNanoseconds() const {
return (unsigned int)(getCurrentTicks() - m_ticks);
}
unsigned int Timer::getElapsedMilliseconds() const {
INTERNAL_CATCH_INLINE unsigned int Timer::getElapsedMilliseconds() const {
return (unsigned int)((getCurrentTicks() - m_ticks)/1000);
}
double Timer::getElapsedSeconds() const {
INTERNAL_CATCH_INLINE double Timer::getElapsedSeconds() const {
return (getCurrentTicks() - m_ticks)/1000000.0;
}

View File

@ -31,7 +31,13 @@ namespace Catch {
void operator=( Version const& );
};
extern Version libraryVersion;
template <typename T>
struct LibraryVersionInfo
{
static const T value;
};
typedef LibraryVersionInfo<Version> libraryVersion;
}
#endif // TWOBLUECUBES_CATCH_VERSION_H_INCLUDED

View File

@ -13,7 +13,9 @@
namespace Catch {
// These numbers are maintained by a script
Version libraryVersion( 1, 0, 11, "master" );
template <typename T>
const T LibraryVersionInfo<T>::value( 1, 0, 11, "master" );
}
#endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED

View File

@ -0,0 +1,16 @@
/*
* Created by Malcolm on 10/11/2013.
* Copyright 2013 Malcolm Noyes
*
* 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_VS_MANAGED_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_VS_MANAGED_HPP_INCLUDED
#ifdef INTERNAL_CATCH_VS_MANAGED
#endif
#endif // TWOBLUECUBES_CATCH_HPP_INCLUDED

View File

@ -0,0 +1,16 @@
/*
* Created by Malcolm on 10/11/2013.
* Copyright 2013 Malcolm Noyes
*
* 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_VS_NATIVE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_VS_NATIVE_HPP_INCLUDED
#ifdef INTERNAL_CATCH_VS_NATIVE
#endif
#endif // TWOBLUECUBES_CATCH_VS_NATIVE_HPP_INCLUDED

View File

@ -249,11 +249,11 @@ namespace Catch {
stream << "\n" << getTildes() << "\n";
Colour colour( Colour::SecondaryText );
stream << currentTestRunInfo->name
<< " is a Catch v" << libraryVersion.majorVersion << "."
<< libraryVersion.minorVersion << " b"
<< libraryVersion.buildNumber;
if( libraryVersion.branchName != "master" )
stream << " (" << libraryVersion.branchName << ")";
<< " is a Catch v" << libraryVersion::value.majorVersion << "."
<< libraryVersion::value.minorVersion << " b"
<< libraryVersion::value.buildNumber;
if( libraryVersion::value.branchName != "master" )
stream << " (" << libraryVersion::value.branchName << ")";
stream << " host application.\n"
<< "Run with -? for options\n\n";

View File

@ -180,6 +180,8 @@
<ClInclude Include="..\..\..\..\include\internal\catch_totals.hpp" />
<ClInclude Include="..\..\..\..\include\internal\catch_version.h" />
<ClInclude Include="..\..\..\..\include\internal\catch_version.hpp" />
<ClInclude Include="..\..\..\..\include\internal\catch_vs_managed_impl.hpp" />
<ClInclude Include="..\..\..\..\include\internal\catch_vs_native_impl.hpp" />
<ClInclude Include="..\..\..\..\include\internal\catch_xmlwriter.hpp" />
<ClInclude Include="..\..\..\..\include\reporters\catch_reporter_console.hpp" />
<ClInclude Include="..\..\..\..\include\reporters\catch_reporter_junit.hpp" />

View File

@ -5,7 +5,7 @@ import datetime
from scriptCommon import catchPath
versionParser = re.compile( r'(\s*Version\slibraryVersion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*\).*' )
versionParser = re.compile( r'(\s*const\sT\sLibraryVersionInfo<T>::value)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*\).*' )
includesParser = re.compile( r'\s*#include\s*"(.*)"' )
guardParser = re.compile( r'\s*#.*_INCLUDED')
defineParser = re.compile( r'\s*#define')