diff --git a/tests/custom_interval_tests.hpp b/tests/custom_interval_tests.hpp new file mode 100644 index 0000000..8c97518 --- /dev/null +++ b/tests/custom_interval_tests.hpp @@ -0,0 +1,152 @@ +#pragma once + +#include "test_utility.hpp" +#include "multi_join_interval.hpp" + +#include +#include +#include +#include + +class CustomIntervalTests : public ::testing::Test +{}; + +template +struct custom_interval : public lib_interval_tree::interval +{ + public: + using value_type = numerical_type; + using interval_kind = interval_kind_; + + using lib_interval_tree::interval::low_; + using lib_interval_tree::interval::high_; + + /** + * Constructs an custom_interval. low MUST be smaller than high. + */ + custom_interval(value_type low, value_type high) + : lib_interval_tree::interval{low, high} + {} + + std::function on_overlaps; + bool overlaps(custom_interval const& other) const + { + if (on_overlaps) + return on_overlaps(other.low_, other.high_); + return interval_kind::overlaps(low_, high_, other.low_, other.high_); + } + + std::function on_overlaps_exclusive_ival; + bool overlaps_exclusive(custom_interval const& other) const + { + if (on_overlaps_exclusive_ival) + return on_overlaps_exclusive_ival(other); + return low_ < other.high_ && other.low_ < high_; + } + + std::function on_join; + custom_interval join(custom_interval const& other) const + { + if (on_join) + return on_join(other); + return {std::min(low_, other.low_), std::max(high_, other.high_)}; + } +}; + +struct minimal_custom_interval : public lib_interval_tree::interval +{ + using lib_interval_tree::interval::interval; + + minimal_custom_interval join(minimal_custom_interval const& other) const + { + return {std::min(low_, other.low_), std::max(high_, other.high_)}; + } +}; + +TEST_F(CustomIntervalTests, CanInsertCustomIntervalJoined) +{ + lib_interval_tree::interval_tree> tree; + tree.insert({0, 5}); + tree.insert_overlap({4, 10}); + + ASSERT_EQ(tree.size(), 1); + EXPECT_EQ(tree.begin()->low(), 0); + EXPECT_EQ(tree.begin()->high(), 10); +} + +TEST_F(CustomIntervalTests, CustomJoinIsCalled) +{ + lib_interval_tree::interval_tree> tree; + auto ival1 = custom_interval{0, 5}; + auto ival2 = custom_interval{4, 10}; + + bool join_called = false; + ival1.on_join = [&](custom_interval const& other) -> custom_interval { + join_called = true; + return {std::min(ival1.low_, other.low_), std::max(ival1.high_, other.high_)}; + }; + + tree.insert(ival1); + tree.insert_overlap(ival2); + + EXPECT_TRUE(join_called); +} + +TEST_F(CustomIntervalTests, CustomOverlapsIsCalled) +{ + lib_interval_tree::interval_tree> tree; + auto ival1 = custom_interval{0, 5}; + auto ival2 = custom_interval{4, 10}; + + bool overlaps_called = false; + ival1.on_overlaps = [&](int l, int h) -> bool { + overlaps_called = true; + return custom_interval::interval_kind::overlaps(ival1.low_, ival1.high_, l, h); + }; + + tree.insert(ival1); + tree.insert_overlap(ival2); + + EXPECT_TRUE(overlaps_called); +} + +TEST_F(CustomIntervalTests, CustomOverlapsExclusiveIvalIsCalled) +{ + lib_interval_tree::interval_tree> tree; + auto ival1 = custom_interval{0, 5}; + auto ival2 = custom_interval{4, 10}; + + bool overlaps_exclusive_ival_called = false; + ival1.on_overlaps_exclusive_ival = [&](custom_interval const& other) -> bool { + overlaps_exclusive_ival_called = true; + return ival1.low_ < other.high_ && other.low_ < ival1.high_; + }; + + tree.insert(ival1); + tree.insert_overlap(ival2, true); + + EXPECT_TRUE(overlaps_exclusive_ival_called); +} + +TEST_F(CustomIntervalTests, CanUseMinimalCustomInterval) +{ + lib_interval_tree::interval_tree tree; + tree.insert({0, 5}); + tree.insert_overlap({4, 10}); + tree.erase(tree.begin()); + + EXPECT_EQ(tree.size(), 0); + + tree.insert({0, 5}); + tree.insert({7, 10}); + auto iter = tree.find({0, 5}); + ASSERT_NE(iter, tree.end()); + EXPECT_EQ(iter->low(), 0); + EXPECT_EQ(iter->high(), 5); + + tree.deoverlap(); + auto iter2 = tree.overlap_find({8, 12}); + ASSERT_NE(iter2, tree.end()); + EXPECT_EQ(iter2->low(), 7); + EXPECT_EQ(iter2->high(), 10); +} \ No newline at end of file diff --git a/tests/tests.cpp b/tests/tests.cpp index def3a02..de6ab1a 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -14,6 +14,7 @@ #include "float_overlap_tests.hpp" #include "iteration_tests.hpp" #include "hook_tests.hpp" +#include "custom_interval_tests.hpp" int main(int argc, char** argv) {