mirror of
https://github.com/boostorg/unordered.git
synced 2025-08-01 04:14:29 +02:00
Merge exception tests
This commit is contained in:
@@ -92,4 +92,5 @@ test-suite unordered-exception
|
|||||||
[ run exception/rehash_exception_tests.cpp framework ]
|
[ run exception/rehash_exception_tests.cpp framework ]
|
||||||
[ run exception/swap_exception_tests.cpp framework : : :
|
[ run exception/swap_exception_tests.cpp framework : : :
|
||||||
<define>BOOST_UNORDERED_SWAP_METHOD=2 ]
|
<define>BOOST_UNORDERED_SWAP_METHOD=2 ]
|
||||||
|
[ run exception/merge_exception_tests.cpp framework ]
|
||||||
;
|
;
|
||||||
|
108
test/exception/merge_exception_tests.cpp
Normal file
108
test/exception/merge_exception_tests.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#include "../helpers/exception_test.hpp"
|
||||||
|
#include "../helpers/invariants.hpp"
|
||||||
|
#include "../helpers/metafunctions.hpp"
|
||||||
|
#include "../helpers/random_values.hpp"
|
||||||
|
#include "./containers.hpp"
|
||||||
|
|
||||||
|
template <typename T1, typename T2> void merge_exception_test(T1 x, T2 y)
|
||||||
|
{
|
||||||
|
std::size_t size = x.size() + y.size();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ENABLE_EXCEPTIONS;
|
||||||
|
x.merge(y);
|
||||||
|
} catch (...) {
|
||||||
|
test::check_equivalent_keys(x);
|
||||||
|
test::check_equivalent_keys(y);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a full check, just want to make sure the merge completed.
|
||||||
|
BOOST_TEST(size == x.size() + y.size());
|
||||||
|
if (y.size()) {
|
||||||
|
BOOST_TEST(test::has_unique_keys<T1>::value);
|
||||||
|
for (typename T2::iterator it = y.begin(); it != y.end(); ++it) {
|
||||||
|
BOOST_TEST(x.find(test::get_key<T2>(*it)) != x.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test::check_equivalent_keys(x);
|
||||||
|
test::check_equivalent_keys(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
void merge_exception_test(T1 const*, T2 const*, std::size_t count1,
|
||||||
|
std::size_t count2, int tag1, int tag2, test::random_generator gen1,
|
||||||
|
test::random_generator gen2)
|
||||||
|
{
|
||||||
|
test::random_values<T1> v1(count1, gen1);
|
||||||
|
test::random_values<T2> v2(count2, gen2);
|
||||||
|
T1 x(v1.begin(), v1.end(), 0, test::exception::hash(tag1),
|
||||||
|
test::exception::equal_to(tag1));
|
||||||
|
T2 y(v2.begin(), v2.end(), 0, test::exception::hash(tag2),
|
||||||
|
test::exception::equal_to(tag2));
|
||||||
|
|
||||||
|
EXCEPTION_LOOP(merge_exception_test(x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::unordered_set<test::exception::object, test::exception::hash,
|
||||||
|
test::exception::equal_to,
|
||||||
|
test::exception::allocator<test::exception::object> >* test_set_;
|
||||||
|
boost::unordered_multiset<test::exception::object, test::exception::hash,
|
||||||
|
test::exception::equal_to,
|
||||||
|
test::exception::allocator<test::exception::object> >* test_multiset_;
|
||||||
|
boost::unordered_map<test::exception::object, test::exception::object,
|
||||||
|
test::exception::hash, test::exception::equal_to,
|
||||||
|
test::exception::allocator2<test::exception::object> >* test_map_;
|
||||||
|
boost::unordered_multimap<test::exception::object, test::exception::object,
|
||||||
|
test::exception::hash, test::exception::equal_to,
|
||||||
|
test::exception::allocator2<test::exception::object> >* test_multimap_;
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
UNORDERED_TEST(merge_exception_test,
|
||||||
|
((test_set_)(test_multiset_))
|
||||||
|
((test_set_)(test_multiset_))
|
||||||
|
((0)(10)(100))
|
||||||
|
((0)(10)(100))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
)
|
||||||
|
UNORDERED_TEST(merge_exception_test,
|
||||||
|
((test_map_)(test_multimap_))
|
||||||
|
((test_map_)(test_multimap_))
|
||||||
|
((0)(10)(100))
|
||||||
|
((0)(10)(100))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
)
|
||||||
|
// Run fewer generate_collisions tests, as they're slow.
|
||||||
|
UNORDERED_TEST(merge_exception_test,
|
||||||
|
((test_set_)(test_multiset_))
|
||||||
|
((test_set_)(test_multiset_))
|
||||||
|
((10))
|
||||||
|
((10))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((generate_collisions))
|
||||||
|
((generate_collisions))
|
||||||
|
)
|
||||||
|
UNORDERED_TEST(merge_exception_test,
|
||||||
|
((test_map_)(test_multimap_))
|
||||||
|
((test_map_)(test_multimap_))
|
||||||
|
((10))
|
||||||
|
((10))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((generate_collisions))
|
||||||
|
((generate_collisions))
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RUN_TESTS()
|
@@ -275,6 +275,77 @@ template <class Test> void exception_safety(Test const& f, char const* /*name*/)
|
|||||||
}
|
}
|
||||||
runner.end();
|
runner.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// An alternative way to run exception tests.
|
||||||
|
// See merge_exception_tests.cpp for an example.
|
||||||
|
|
||||||
|
struct exception_looper
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
unsigned int failure_count;
|
||||||
|
char const* error_msg;
|
||||||
|
int error_count;
|
||||||
|
|
||||||
|
exception_looper() : success(false), failure_count(0), error_msg(0) {}
|
||||||
|
|
||||||
|
void start() { iteration = 0; }
|
||||||
|
|
||||||
|
bool loop_condition() const
|
||||||
|
{
|
||||||
|
return !error_msg && !success && failure_count < 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_iteration()
|
||||||
|
{
|
||||||
|
error_count = boost::detail::test_errors();
|
||||||
|
++iteration;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void successful_run() { success = true; }
|
||||||
|
|
||||||
|
void test_failure_caught(test_failure const&)
|
||||||
|
{
|
||||||
|
error_msg = "test_failure caught.";
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_exception_caught(test_exception const& e)
|
||||||
|
{
|
||||||
|
if (error_count != boost::detail::test_errors()) {
|
||||||
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||||
|
<< "Iteration: " << iteration
|
||||||
|
<< " Error found for epoint: " << e.name << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unexpected_exception_caught() { error_msg = "Unexpected exception."; }
|
||||||
|
|
||||||
|
void end()
|
||||||
|
{
|
||||||
|
if (error_msg) {
|
||||||
|
BOOST_ERROR(error_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EXCEPTION_LOOP(op) \
|
||||||
|
test::lightweight::exception_looper looper; \
|
||||||
|
looper.start(); \
|
||||||
|
while (looper.loop_condition()) { \
|
||||||
|
looper.start_iteration(); \
|
||||||
|
try { \
|
||||||
|
op; \
|
||||||
|
looper.successful_run(); \
|
||||||
|
} catch (test::lightweight::test_failure e) { \
|
||||||
|
looper.test_failure_caught(e); \
|
||||||
|
} catch (test::lightweight::test_exception e) { \
|
||||||
|
looper.test_exception_caught(e); \
|
||||||
|
} catch (...) { \
|
||||||
|
looper.unexpected_exception_caught(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
looper.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,8 +10,9 @@
|
|||||||
|
|
||||||
#include "../helpers/count.hpp"
|
#include "../helpers/count.hpp"
|
||||||
#include "../helpers/fwd.hpp"
|
#include "../helpers/fwd.hpp"
|
||||||
|
#include "../helpers/generators.hpp"
|
||||||
#include "../helpers/memory.hpp"
|
#include "../helpers/memory.hpp"
|
||||||
#include "../objects/fwd.hpp"
|
#include "./fwd.hpp"
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
Reference in New Issue
Block a user