Catch/include/internal/catch_test_case_registry_impl.hpp

149 lines
5.5 KiB
C++
Raw Normal View History

2011-01-07 05:22:24 -05:00
/*
* Created by Phil on 7/1/2011
* Copyright 2010 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_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
2011-01-07 05:22:24 -05:00
#include "catch_test_registry.hpp"
2012-08-14 14:30:30 -04:00
#include "catch_test_case_info.h"
#include "catch_test_spec.h"
#include "catch_context.h"
2011-01-07 05:22:24 -05:00
#include <vector>
#include <set>
#include <sstream>
#include <iostream>
2011-01-07 05:22:24 -05:00
2012-05-16 03:02:20 -04:00
namespace Catch {
2012-05-10 16:46:46 -04:00
class TestRegistry : public ITestCaseRegistry {
2011-01-07 05:22:24 -05:00
public:
2012-05-10 16:46:46 -04:00
TestRegistry() : m_unnamedCount( 0 ) {}
virtual ~TestRegistry();
2011-01-07 05:22:24 -05:00
virtual void registerTest( const TestCase& testCase ) {
std::string name = testCase.getTestCaseInfo().name;
if( name == "" ) {
std::ostringstream oss;
oss << name << "unnamed/" << ++m_unnamedCount;
return registerTest( testCase.withName( oss.str() ) );
}
2012-05-10 16:46:46 -04:00
if( m_functions.find( testCase ) == m_functions.end() ) {
m_functions.insert( testCase );
m_functionsInOrder.push_back( testCase );
if( !testCase.isHidden() )
m_nonHiddenFunctions.push_back( testCase );
2011-01-07 05:22:24 -05:00
}
2012-05-10 16:46:46 -04:00
else {
const TestCase& prev = *m_functions.find( testCase );
std::cerr << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
<< "\tFirst seen at " << SourceLineInfo( prev.getTestCaseInfo().lineInfo ) << "\n"
<< "\tRedefined at " << SourceLineInfo( testCase.getTestCaseInfo().lineInfo ) << std::endl;
exit(1);
}
2011-01-07 05:22:24 -05:00
}
2012-11-22 14:17:20 -05:00
virtual const std::vector<TestCase>& getAllTests() const {
2011-01-07 05:22:24 -05:00
return m_functionsInOrder;
}
2012-11-22 14:17:20 -05:00
virtual const std::vector<TestCase>& getAllNonHiddenTests() const {
return m_nonHiddenFunctions;
}
2012-08-23 15:08:50 -04:00
// !TBD deprecated
2012-11-22 14:17:20 -05:00
virtual std::vector<TestCase> getMatchingTestCases( const std::string& rawTestSpec ) const {
std::vector<TestCase> matchingTests;
getMatchingTestCases( rawTestSpec, matchingTests );
return matchingTests;
}
2012-08-23 15:08:50 -04:00
// !TBD deprecated
2012-11-22 14:17:20 -05:00
virtual void getMatchingTestCases( const std::string& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const {
2012-08-23 15:08:50 -04:00
TestCaseFilter filter( rawTestSpec );
2012-11-22 14:17:20 -05:00
std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
2012-05-10 16:46:46 -04:00
for(; it != itEnd; ++it ) {
2012-08-23 15:08:50 -04:00
if( filter.shouldInclude( *it ) ) {
matchingTestsOut.push_back( *it );
}
}
}
2012-11-22 14:17:20 -05:00
virtual void getMatchingTestCases( const TestCaseFilters& filters, std::vector<TestCase>& matchingTestsOut ) const {
std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
2012-08-23 15:08:50 -04:00
// !TBD: replace with algorithm
for(; it != itEnd; ++it )
if( filters.shouldInclude( *it ) )
matchingTestsOut.push_back( *it );
}
2011-01-07 05:22:24 -05:00
private:
2012-11-22 14:17:20 -05:00
std::set<TestCase> m_functions;
std::vector<TestCase> m_functionsInOrder;
std::vector<TestCase> m_nonHiddenFunctions;
size_t m_unnamedCount;
2011-01-07 05:22:24 -05:00
};
2011-01-28 13:56:26 -05:00
///////////////////////////////////////////////////////////////////////////
2011-01-07 05:22:24 -05:00
2012-08-14 03:38:22 -04:00
class FreeFunctionTestCase : public SharedImpl<ITestCase> {
2012-05-10 16:46:46 -04:00
public:
FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
2012-08-14 03:38:22 -04:00
2012-05-10 16:46:46 -04:00
virtual void invoke() const {
2011-01-31 05:10:20 -05:00
m_fun();
2011-01-07 05:22:24 -05:00
}
2012-08-14 03:38:22 -04:00
2011-01-07 05:22:24 -05:00
private:
2012-08-14 03:38:22 -04:00
virtual ~FreeFunctionTestCase();
2011-01-31 05:10:20 -05:00
TestFunction m_fun;
2011-01-07 05:22:24 -05:00
};
inline std::string extractClassName( const std::string& classOrQualifiedMethodName ) {
std::string className = classOrQualifiedMethodName;
if( className[0] == '&' )
{
std::size_t lastColons = className.rfind( "::" );
std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
if( penultimateColons == std::string::npos )
penultimateColons = 1;
className = className.substr( penultimateColons, lastColons-penultimateColons );
}
return className;
}
2011-01-07 05:22:24 -05:00
///////////////////////////////////////////////////////////////////////////
2012-05-10 16:46:46 -04:00
AutoReg::AutoReg( TestFunction function,
const char* name,
const char* description,
const SourceLineInfo& lineInfo ) {
registerTestCase( new FreeFunctionTestCase( function ), "global", name, description, lineInfo );
2011-01-07 05:22:24 -05:00
}
2012-05-10 16:46:46 -04:00
AutoReg::~AutoReg() {}
2011-01-07 05:22:24 -05:00
void AutoReg::registerTestCase( ITestCase* testCase,
const char* classOrQualifiedMethodName,
const char* name,
2012-05-10 16:46:46 -04:00
const char* description,
const SourceLineInfo& lineInfo ) {
getMutableRegistryHub().registerTest( makeTestCase( testCase, extractClassName( classOrQualifiedMethodName ), name, description, lineInfo ) );
2011-01-07 05:22:24 -05:00
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED