mirror of https://github.com/catchorg/Catch2.git
Refactor implementation of hashed random order test sorting
This commit is contained in:
parent
a2fc7cf8c0
commit
bad0fb51f8
|
@ -16,14 +16,13 @@
|
||||||
#include "catch_test_case_info.h"
|
#include "catch_test_case_info.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
|
||||||
#include <random>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct HashTest {
|
namespace {
|
||||||
explicit HashTest( Catch::SimplePcg32& rng ) {
|
struct TestHasher {
|
||||||
|
explicit TestHasher(Catch::SimplePcg32& rng) {
|
||||||
basis = rng();
|
basis = rng();
|
||||||
basis <<= 32;
|
basis <<= 32;
|
||||||
basis |= rng();
|
basis |= rng();
|
||||||
|
@ -31,48 +30,61 @@ namespace Catch {
|
||||||
|
|
||||||
uint64_t basis;
|
uint64_t basis;
|
||||||
|
|
||||||
uint64_t operator()( TestCase const& t ) const {
|
uint64_t operator()(TestCase const& t) const {
|
||||||
// Modified FNV-1a hash
|
// Modified FNV-1a hash
|
||||||
static constexpr uint64_t prime = 1099511628211;
|
static constexpr uint64_t prime = 1099511628211;
|
||||||
uint64_t hash = basis;
|
uint64_t hash = basis;
|
||||||
for( const char c : t.name ) {
|
for (const char c : t.name) {
|
||||||
hash ^= c;
|
hash ^= c;
|
||||||
hash *= prime;
|
hash *= prime;
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // end unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
|
std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
|
||||||
switch( config.runOrder() ) {
|
switch( config.runOrder() ) {
|
||||||
|
case RunTests::InDeclarationOrder:
|
||||||
|
// already in declaration order
|
||||||
|
break;
|
||||||
|
|
||||||
case RunTests::InLexicographicalOrder: {
|
case RunTests::InLexicographicalOrder: {
|
||||||
std::vector<TestCase> sorted = unsortedTestCases;
|
std::vector<TestCase> sorted = unsortedTestCases;
|
||||||
std::sort( sorted.begin(), sorted.end() );
|
std::sort( sorted.begin(), sorted.end() );
|
||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RunTests::InRandomOrder: {
|
case RunTests::InRandomOrder: {
|
||||||
seedRng( config );
|
seedRng( config );
|
||||||
HashTest h( rng() );
|
TestHasher h( rng() );
|
||||||
std::vector<std::tuple<uint64_t, std::string, TestCase const*>> indexed_tests;
|
|
||||||
|
using hashedTest = std::pair<uint64_t, TestCase const*>;
|
||||||
|
std::vector<hashedTest> indexed_tests;
|
||||||
indexed_tests.reserve( unsortedTestCases.size() );
|
indexed_tests.reserve( unsortedTestCases.size() );
|
||||||
std::transform( unsortedTestCases.begin(), unsortedTestCases.end(),
|
|
||||||
std::back_inserter( indexed_tests ),
|
for (auto const& testCase : unsortedTestCases) {
|
||||||
[&]( TestCase const& t ) {
|
indexed_tests.emplace_back(h(testCase), &testCase);
|
||||||
return std::make_tuple( h(t), t.name, &t );
|
}
|
||||||
} );
|
|
||||||
std::sort( indexed_tests.begin(), indexed_tests.end() );
|
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;
|
std::vector<TestCase> sorted;
|
||||||
sorted.reserve( unsortedTestCases.size() );
|
sorted.reserve( indexed_tests.size() );
|
||||||
std::transform( indexed_tests.begin(), indexed_tests.end(),
|
|
||||||
std::back_inserter( sorted ),
|
for (auto const& hashed : indexed_tests) {
|
||||||
[]( std::tuple<uint64_t, std::string, TestCase const*> const& t ) {
|
sorted.emplace_back(*hashed.second);
|
||||||
return *std::get<2>( t );
|
}
|
||||||
} );
|
|
||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
case RunTests::InDeclarationOrder:
|
|
||||||
// already in declaration order
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return unsortedTestCases;
|
return unsortedTestCases;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue