Tag aliases feature

This commit is contained in:
Phil Nash
2014-06-30 07:33:17 +01:00
parent 006aafd982
commit 1d210ebd37
13 changed files with 243 additions and 8 deletions

View File

@@ -84,7 +84,7 @@ namespace Catch {
m_os( std::cout.rdbuf() )
{
if( !data.testsOrTags.empty() ) {
TestSpecParser parser;
TestSpecParser parser( ITagAliasRegistry::get() );
for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
parser.parse( data.testsOrTags[i] );
m_testSpec = parser.testSpec();

View File

@@ -34,6 +34,7 @@
#include "catch_debugger.hpp"
#include "catch_tostring.hpp"
#include "catch_result_builder.hpp"
#include "catch_tag_alias_registry.hpp"
#include "../reporters/catch_reporter_xml.hpp"
#include "../reporters/catch_reporter_junit.hpp"

View File

@@ -0,0 +1,26 @@
/*
* Created by Phil on 27/6/2014.
* Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
*
* 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_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
#include "catch_tag_alias.h"
#include "catch_option.hpp"
namespace Catch {
struct ITagAliasRegistry {
virtual ~ITagAliasRegistry();
virtual Option<TagAlias> find( std::string const& alias ) const = 0;
virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
static ITagAliasRegistry const& get();
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED

View File

@@ -26,7 +26,7 @@ namespace Catch {
std::cout << "Matching test cases:\n";
else {
std::cout << "All available test cases:\n";
testSpec = TestSpecParser().parse( "*" ).testSpec();
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
}
std::size_t matchedTests = 0;
@@ -61,7 +61,7 @@ namespace Catch {
inline std::size_t listTestsNamesOnly( Config const& config ) {
TestSpec testSpec = config.testSpec();
if( !config.testSpec().hasFilters() )
testSpec = TestSpecParser().parse( "*" ).testSpec();
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
std::size_t matchedTests = 0;
std::vector<TestCase> matchedTestCases;
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
@@ -99,7 +99,7 @@ namespace Catch {
std::cout << "Tags for matching test cases:\n";
else {
std::cout << "All available tags:\n";
testSpec = TestSpecParser().parse( "*" ).testSpec();
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
}
std::map<std::string, TagInfo> tagCounts;

View File

@@ -0,0 +1,32 @@
/*
* Created by Phil on 27/6/2014.
* Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
*
* 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_TAG_ALIAS_H_INCLUDED
#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
#include "catch_common.h"
#include <string>
namespace Catch {
struct TagAlias {
TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
std::string tag;
SourceLineInfo lineInfo;
};
struct RegistrarForTagAliases {
RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }

View File

@@ -0,0 +1,31 @@
/*
* Created by Phil on 27/6/2014.
* Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
*
* 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_TAG_ALIAS_REGISTRY_H_INCLUDED
#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
#include "catch_interfaces_tag_alias_registry.h"
#include <map>
namespace Catch {
class TagAliasRegistry : public ITagAliasRegistry {
public:
virtual ~TagAliasRegistry();
virtual Option<TagAlias> find( std::string const& alias ) const;
virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
static TagAliasRegistry& get();
private:
std::map<std::string, TagAlias> m_registry;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED

View File

@@ -0,0 +1,83 @@
/*
* Created by Phil on 27/6/2014.
* Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
*
* 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_TAG_ALIAS_REGISTRY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
#include "catch_tag_alias_registry.h"
#include "catch_console_colour.hpp"
#include <map>
#include <iostream>
namespace Catch {
TagAliasRegistry::~TagAliasRegistry() {}
Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
if( it != m_registry.end() )
return it->second;
else
return Option<TagAlias>();
}
std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
std::string expandedTestSpec = unexpandedTestSpec;
for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
it != itEnd;
++it ) {
std::size_t pos = expandedTestSpec.find( it->first );
if( pos != std::string::npos ) {
expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
it->second.tag +
expandedTestSpec.substr( pos + it->first.size() );
}
}
return expandedTestSpec;
}
void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
std::ostringstream oss;
oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
throw std::domain_error( oss.str().c_str() );
}
if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
std::ostringstream oss;
oss << "error: tag alias, \"" << alias << "\" already registered.\n"
<< "\tFirst seen at " << find(alias)->lineInfo << "\n"
<< "\tRedefined at " << lineInfo;
throw std::domain_error( oss.str().c_str() );
}
}
TagAliasRegistry& TagAliasRegistry::get() {
static TagAliasRegistry instance;
return instance;
}
ITagAliasRegistry::~ITagAliasRegistry() {}
ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
try {
TagAliasRegistry::get().add( alias, tag, lineInfo );
}
catch( std::exception& ex ) {
Colour colourGuard( Colour::Red );
std::cerr << ex.what() << std::endl;
exit(1);
}
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED

View File

@@ -14,6 +14,7 @@
#endif
#include "catch_test_spec.hpp"
#include "catch_interfaces_tag_alias_registry.h"
namespace Catch {
@@ -25,13 +26,16 @@ namespace Catch {
std::string m_arg;
TestSpec::Filter m_currentFilter;
TestSpec m_testSpec;
ITagAliasRegistry const& m_tagAliases;
public:
TestSpecParser parse( std::string const& arg ) {
TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( tagAliases ) {}
TestSpecParser& parse( std::string const& arg ) {
m_mode = None;
m_exclusion = false;
m_start = std::string::npos;
m_arg = arg;
m_arg = m_tagAliases.expandAliases( arg );
for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
visitChar( m_arg[m_pos] );
if( m_mode == Name )
@@ -100,7 +104,7 @@ namespace Catch {
}
};
inline TestSpec parseTestSpec( std::string const& arg ) {
return TestSpecParser().parse( arg ).testSpec();
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
}
} // namespace Catch