| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 | 
							- /*
 
-  *  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 <algorithm>
 
- #include <sstream>
 
- namespace Catch {
 
-     namespace {
 
-         struct TestHasher {
 
-             using hash_t = uint64_t;
 
-             explicit TestHasher( hash_t hashSuffix ):
 
-                 m_hashSuffix{ hashSuffix } {}
 
-             uint32_t operator()( TestCase const& t ) const {
 
-                 // FNV-1a hash with multiplication fold.
 
-                 const hash_t prime = 1099511628211u;
 
-                 hash_t hash = 14695981039346656037u;
 
-                 for ( const char c : t.name ) {
 
-                     hash ^= c;
 
-                     hash *= prime;
 
-                 }
 
-                 hash ^= m_hashSuffix;
 
-                 hash *= prime;
 
-                 const uint32_t low{ static_cast<uint32_t>( hash ) };
 
-                 const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };
 
-                 return low * high;
 
-             }
 
-         private:
 
-             hash_t m_hashSuffix;
 
-         };
 
-     } // end unnamed namespace
 
-     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
 
-         switch( config.runOrder() ) {
 
-             case RunTests::InDeclarationOrder:
 
-                 // already in declaration order
 
-                 break;
 
-             case RunTests::InLexicographicalOrder: {
 
-                 std::vector<TestCase> sorted = unsortedTestCases;
 
-                 std::sort( sorted.begin(), sorted.end() );
 
-                 return sorted;
 
-             }
 
-             case RunTests::InRandomOrder: {
 
-                 seedRng( config );
 
-                 TestHasher h{ config.rngSeed() };
 
-                 using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
 
-                 std::vector<hashedTest> indexed_tests;
 
-                 indexed_tests.reserve( unsortedTestCases.size() );
 
-                 for (auto const& testCase : unsortedTestCases) {
 
-                     indexed_tests.emplace_back(h(testCase), &testCase);
 
-                 }
 
-                 std::sort(indexed_tests.begin(), indexed_tests.end(),
 
-                           [](hashedTest const& lhs, hashedTest const& rhs) {
 
-                           if (lhs.first == rhs.first) {
 
-                               return lhs.second->name < rhs.second->name;
 
-                           }
 
-                           return lhs.first < rhs.first;
 
-                 });
 
-                 std::vector<TestCase> sorted;
 
-                 sorted.reserve( indexed_tests.size() );
 
-                 for (auto const& hashed : indexed_tests) {
 
-                     sorted.emplace_back(*hashed.second);
 
-                 }
 
-                 return sorted;
 
-             }
 
-         }
 
-         return unsortedTestCases;
 
-     }
 
-     bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
 
-         return !testCase.throws() || config.allowThrows();
 
-     }
 
-     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
 
-         return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
 
-     }
 
-     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
 
-         std::set<TestCase> seenFunctions;
 
-         for( auto const& function : functions ) {
 
-             auto prev = seenFunctions.insert( function );
 
-             CATCH_ENFORCE( prev.second,
 
-                     "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
 
-                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
 
-                     << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
 
-         }
 
-     }
 
-     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
 
-         std::vector<TestCase> filtered;
 
-         filtered.reserve( testCases.size() );
 
-         for (auto const& testCase : testCases) {
 
-             if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
 
-                 (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
 
-                 filtered.push_back(testCase);
 
-             }
 
-         }
 
-         return filtered;
 
-     }
 
-     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
 
-         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
 
-     }
 
-     void TestRegistry::registerTest( TestCase const& testCase ) {
 
-         std::string name = testCase.getTestCaseInfo().name;
 
-         if( name.empty() ) {
 
-             ReusableStringStream rss;
 
-             rss << "Anonymous test case " << ++m_unnamedCount;
 
-             return registerTest( testCase.withName( rss.str() ) );
 
-         }
 
-         m_functions.push_back( testCase );
 
-     }
 
-     std::vector<TestCase> const& TestRegistry::getAllTests() const {
 
-         return m_functions;
 
-     }
 
-     std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
 
-         if( m_sortedFunctions.empty() )
 
-             enforceNoDuplicateTestCases( m_functions );
 
-         if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
 
-             m_sortedFunctions = sortTests( config, m_functions );
 
-             m_currentSortOrder = config.runOrder();
 
-         }
 
-         return m_sortedFunctions;
 
-     }
 
-     ///////////////////////////////////////////////////////////////////////////
 
-     TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
 
-     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
 
 
  |