/* * Created by Martin on 25/07/2017 * * 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) */ #include "catch_test_case_registry_impl.h" #include "catch_context.h" #include "catch_enforce.h" #include "catch_interfaces_registry_hub.h" #include "catch_random_number_generator.h" #include "catch_run_context.h" #include "catch_string_manip.h" #include "catch_test_case_info.h" #include namespace Catch { std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { std::vector sorted = unsortedTestCases; switch( config.runOrder() ) { case RunTests::InLexicographicalOrder: std::sort( sorted.begin(), sorted.end() ); break; case RunTests::InRandomOrder: seedRng( config ); std::shuffle( sorted.begin(), sorted.end(), rng() ); break; case RunTests::InDeclarationOrder: // already in declaration order break; } return sorted; } bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config ) { return !testCase.getTestCaseInfo().throws() || config.allowThrows(); } bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config ) { return testSpec.matches( testCase.getTestCaseInfo() ) && isThrowSafe( testCase, config ); } void enforceNoDuplicateTestCases( std::vector const& functions ) { std::set seenFunctions; for( auto const& function : functions ) { auto prev = seenFunctions.insert( function ); CATCH_ENFORCE( prev.second, "error: TEST_CASE( \"" << function.getTestCaseInfo().name << "\" ) already defined.\n" << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" << "\tRedefined at " << function.getTestCaseInfo().lineInfo ); } } std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { std::vector filtered; filtered.reserve( testCases.size() ); for (auto const& testCase : testCases) { if ((!testSpec.hasFilters() && !testCase.getTestCaseInfo().isHidden()) || (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) { filtered.push_back(testCase); } } return filtered; } std::vector const& getAllTestCasesSorted( IConfig const& config ) { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } void TestRegistry::registerTest(std::unique_ptr testInfo, std::unique_ptr testInvoker) { m_handles.emplace_back(testInfo.get(), testInvoker.get()); m_infos.push_back(std::move(testInfo)); m_invokers.push_back(std::move(testInvoker)); } std::vector> const& TestRegistry::getAllInfos() const { return m_infos; } std::vector const& TestRegistry::getAllTests() const { return m_handles; } std::vector const& TestRegistry::getAllTestsSorted( IConfig const& config ) const { if( m_sortedFunctions.empty() ) enforceNoDuplicateTestCases( m_handles ); if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { m_sortedFunctions = sortTests( config, m_handles ); m_currentSortOrder = config.runOrder(); } return m_sortedFunctions; } /////////////////////////////////////////////////////////////////////////// void TestInvokerAsFunction::invoke() const { m_testAsFunction(); } std::string extractClassName( StringRef const& classOrQualifiedMethodName ) { std::string className(classOrQualifiedMethodName); if( startsWith( className, '&' ) ) { 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; } } // end namespace Catch