From 3e1f76dceb397c585f916b8e78d00ae85ac67184 Mon Sep 17 00:00:00 2001 From: Tim Ebbeke Date: Sat, 30 Aug 2025 01:14:54 +0200 Subject: [PATCH] Added two more find tests with larger trees. --- tests/find_tests.hpp | 72 ++++++++++++++++++++++++--------- tests/overlap_find_tests.hpp | 77 ++++++++++++++++++++++++++++-------- 2 files changed, 114 insertions(+), 35 deletions(-) diff --git a/tests/find_tests.hpp b/tests/find_tests.hpp index 2624c69..c1f5429 100644 --- a/tests/find_tests.hpp +++ b/tests/find_tests.hpp @@ -4,15 +4,15 @@ #include #include -class FindTests - : public ::testing::Test +class FindTests : public ::testing::Test { -public: - using types = IntervalTypes ; -protected: - IntervalTypes ::tree_type tree; + public: + using types = IntervalTypes; + + protected: + IntervalTypes::tree_type tree; std::default_random_engine gen; - std::uniform_int_distribution distLarge{-50000, 50000}; + std::uniform_int_distribution distLarge{-50000, 50000}; }; TEST_F(FindTests, WillReturnEndIfTreeIsEmpty) @@ -35,8 +35,7 @@ TEST_F(FindTests, WillFindRoot) TEST_F(FindTests, WillFindRootOnConstTree) { tree.insert({0, 1}); - [](auto const& tree) - { + [](auto const& tree) { EXPECT_EQ(tree.find({0, 1}), std::begin(tree)); }(tree); } @@ -68,7 +67,7 @@ TEST_F(FindTests, WillFindAllInTreeWithDuplicates) tree.insert({5, 8}); tree.insert({5, 8}); int findCount = 0; - tree.find_all({5, 8}, [&findCount](decltype(tree)::iterator iter){ + tree.find_all({5, 8}, [&findCount](decltype(tree)::iterator iter) { ++findCount; EXPECT_EQ(*iter, (decltype(tree)::interval_type{5, 8})); return true; @@ -85,7 +84,7 @@ TEST_F(FindTests, WillFindAllCanExitPreemptively) tree.insert({5, 8}); tree.insert({5, 8}); int findCount = 0; - tree.find_all({5, 8}, [&findCount](decltype(tree)::iterator iter){ + tree.find_all({5, 8}, [&findCount](decltype(tree)::iterator iter) { ++findCount; EXPECT_EQ(*iter, (decltype(tree)::interval_type{5, 8})); return findCount < 3; @@ -97,7 +96,7 @@ TEST_F(FindTests, CanFindAllElementsBack) { constexpr int amount = 10'000; - std::vector intervals; + std::vector intervals; intervals.reserve(amount); for (int i = 0; i != amount; ++i) { @@ -115,11 +114,11 @@ TEST_F(FindTests, CanFindAllElementsBackInStrictlyAscendingNonOverlappingInterva { constexpr int amount = 10'000; - std::vector intervals; + std::vector intervals; intervals.reserve(amount); for (int i = 0; i != amount; ++i) { - const auto interval = lib_interval_tree::make_safe_interval(i * 2, i * 2 + 1); + const auto interval = lib_interval_tree::make_safe_interval(i * 2, i * 2 + 1); intervals.emplace_back(interval); tree.insert(interval); } @@ -133,11 +132,11 @@ TEST_F(FindTests, CanFindAllElementsBackInStrictlyAscendingOverlappingIntervals) { constexpr int amount = 10'000; - std::vector intervals; + std::vector intervals; intervals.reserve(amount); for (int i = 0; i != amount; ++i) { - const auto interval = lib_interval_tree::make_safe_interval(i - 1, i + 1); + const auto interval = lib_interval_tree::make_safe_interval(i - 1, i + 1); intervals.emplace_back(interval); tree.insert(interval); } @@ -153,9 +152,8 @@ TEST_F(FindTests, CanFindAllOnConstTree) tree.insert(targetInterval); tree.insert({8, 9}); tree.insert({25, 30}); - std::vector intervals; - auto findWithConstTree = [&intervals, &targetInterval](auto const& tree) - { + std::vector intervals; + auto findWithConstTree = [&intervals, &targetInterval](auto const& tree) { tree.find_all(targetInterval, [&intervals](auto const& iter) { intervals.emplace_back(*iter); return true; @@ -165,4 +163,40 @@ TEST_F(FindTests, CanFindAllOnConstTree) ASSERT_EQ(intervals.size(), 1); EXPECT_EQ(intervals[0], targetInterval); +} + +TEST_F(FindTests, FuzzyFindAllInTree) +{ + std::mt19937 gen{0}; + std::uniform_int_distribution distSmall{-500, 500}; + + for (int i = 0; i < 200; ++i) + { + const auto generated = distSmall(gen); + tree.insert(lib_interval_tree::make_safe_interval(generated, generated + 20)); + } + const auto searchInterval = decltype(tree)::interval_type{20, 50}; + tree.insert(searchInterval); + tree.insert(searchInterval); + tree.insert(searchInterval); + + int findCount = 0; + bool findIsConsistent = true; + std::vector foundIntervals; + tree.find_all( + searchInterval, + [&findIsConsistent, &searchInterval, &findCount, &foundIntervals](decltype(tree)::iterator iter) { + ++findCount; + if (*iter != searchInterval) + { + findIsConsistent = false; + return false; + } + foundIntervals.emplace_back(*iter); + return true; + } + ); + + EXPECT_EQ(findCount, 3); + ASSERT_TRUE(findIsConsistent); } \ No newline at end of file diff --git a/tests/overlap_find_tests.hpp b/tests/overlap_find_tests.hpp index ee2c027..ed2671b 100644 --- a/tests/overlap_find_tests.hpp +++ b/tests/overlap_find_tests.hpp @@ -2,13 +2,15 @@ #include "test_utility.hpp" -class OverlapFindTests - : public ::testing::Test +#include + +class OverlapFindTests : public ::testing::Test { -public: - using types = IntervalTypes ; -protected: - IntervalTypes ::tree_type tree; + public: + using types = IntervalTypes; + + protected: + IntervalTypes::tree_type tree; }; TEST_F(OverlapFindTests, WillReturnEndIfTreeIsEmpty) @@ -73,19 +75,21 @@ TEST_F(OverlapFindTests, WillFindMultipleOverlaps) tree.insert({10, 15}); tree.insert({15, 20}); - std::vector intervals; + std::vector intervals; tree.overlap_find_all({5, 5}, [&intervals](auto iter) { intervals.push_back(*iter); return true; }); using ::testing::UnorderedElementsAre; - ASSERT_THAT(intervals, UnorderedElementsAre(decltype(tree)::interval_type{0, 5}, decltype(tree)::interval_type{5, 10})); + ASSERT_THAT( + intervals, UnorderedElementsAre(decltype(tree)::interval_type{0, 5}, decltype(tree)::interval_type{5, 10}) + ); } TEST_F(OverlapFindTests, FindAllWillFindNothingIfEmpty) { int findCount = 0; - tree.overlap_find_all({2, 7}, [&findCount](auto){ + tree.overlap_find_all({2, 7}, [&findCount](auto) { ++findCount; return true; }); @@ -100,7 +104,7 @@ TEST_F(OverlapFindTests, FindAllWillFindNothingIfNothingOverlaps) tree.insert({5, 8}); tree.insert({15, 23}); int findCount = 0; - tree.overlap_find_all({1000, 2000}, [&findCount](auto){ + tree.overlap_find_all({1000, 2000}, [&findCount](auto) { ++findCount; return true; }); @@ -116,7 +120,7 @@ TEST_F(OverlapFindTests, FindAllWillFindAllWithLotsOfDuplicates) tree.insert({0, 5}); int findCount = 0; - tree.overlap_find_all({2, 3}, [&findCount](decltype(tree)::iterator iter){ + tree.overlap_find_all({2, 3}, [&findCount](decltype(tree)::iterator iter) { ++findCount; EXPECT_EQ(*iter, (decltype(tree)::interval_type{0, 5})); return true; @@ -133,7 +137,7 @@ TEST_F(OverlapFindTests, CanExitPreemptivelyByReturningFalse) tree.insert({0, 5}); int findCount = 0; - tree.overlap_find_all({2, 3}, [&findCount](decltype(tree)::iterator iter){ + tree.overlap_find_all({2, 3}, [&findCount](decltype(tree)::iterator iter) { ++findCount; EXPECT_EQ(*iter, (decltype(tree)::interval_type{0, 5})); return findCount < 3; @@ -159,15 +163,14 @@ TEST_F(OverlapFindTests, WillFindSingleOverlapInBiggerTree) EXPECT_EQ(iter->high(), 2000); } -TEST_F(FindTests, CanOverlapFindAllOnConstTree) +TEST_F(OverlapFindTests, CanOverlapFindAllOnConstTree) { const auto targetInterval = lib_interval_tree::make_safe_interval(16, 21); tree.insert(targetInterval); tree.insert({8, 9}); tree.insert({25, 30}); - std::vector intervals; - auto findWithConstTree = [&intervals, &targetInterval](auto const& tree) - { + std::vector intervals; + auto findWithConstTree = [&intervals, &targetInterval](auto const& tree) { tree.overlap_find_all(targetInterval, [&intervals](auto const& iter) { intervals.emplace_back(*iter); return true; @@ -178,3 +181,45 @@ TEST_F(FindTests, CanOverlapFindAllOnConstTree) ASSERT_EQ(intervals.size(), 1); EXPECT_EQ(intervals[0], targetInterval); } + +TEST_F(OverlapFindTests, FuzzyOverlapFindAllInTree) +{ + std::mt19937 gen{0}; + std::uniform_int_distribution distSmall{-500, 500}; + + for (int i = 0; i < 200; ++i) + { + const auto generated = distSmall(gen); + tree.insert(lib_interval_tree::make_safe_interval(generated, generated + 20)); + } + + int findCount = 0; + bool findIsConsistent = true; + const auto searchInterval = decltype(tree)::interval_type{20, 50}; + std::vector foundIntervals; + tree.overlap_find_all( + searchInterval, + [&findIsConsistent, &searchInterval, &findCount, &foundIntervals](decltype(tree)::iterator iter) { + ++findCount; + if (!iter->overlaps(searchInterval)) + { + findIsConsistent = false; + return false; + } + foundIntervals.emplace_back(*iter); + return true; + } + ); + + EXPECT_GT(findCount, 0); // Just make sure the test has at least one interval found, or its useless. + ASSERT_TRUE(findIsConsistent); + + // now check that all other intervals should not have been found + for (auto const& ival : tree) + { + if (ival.overlaps(searchInterval)) + { + EXPECT_TRUE(std::find(foundIntervals.begin(), foundIntervals.end(), ival) != foundIntervals.end()); + } + } +}