Skip to content

Commit 4b57ef2

Browse files
committed
Adds leak tests to erase tests.
1 parent 5b11820 commit 4b57ef2

File tree

2 files changed

+100
-10
lines changed

2 files changed

+100
-10
lines changed

tests/erase_tests.hpp

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,94 @@
33
#include <ctime>
44
#include <random>
55
#include <cmath>
6+
#include <iostream>
7+
8+
struct Oracle
9+
{
10+
int livingInstances = 0;
11+
};
12+
13+
template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
14+
class OracleInterval : public lib_interval_tree::interval<numerical_type, interval_kind_>
15+
{
16+
public:
17+
using lib_interval_tree::interval<numerical_type, interval_kind_>::low_;
18+
using lib_interval_tree::interval<numerical_type, interval_kind_>::high_;
19+
20+
OracleInterval(Oracle* oracle, numerical_type start, numerical_type end)
21+
: lib_interval_tree::interval<numerical_type, interval_kind_>(start, end)
22+
, oracle_{oracle}
23+
{
24+
++oracle_->livingInstances;
25+
}
26+
OracleInterval(OracleInterval const& other)
27+
: lib_interval_tree::interval<numerical_type, interval_kind_>(other.low_, other.high_)
28+
, oracle_{other.oracle_}
29+
{
30+
++oracle_->livingInstances;
31+
}
32+
OracleInterval(OracleInterval&& other)
33+
: lib_interval_tree::interval<numerical_type, interval_kind_>(other.low_, other.high_)
34+
, oracle_{other.oracle_}
35+
{
36+
other.oracle_ = nullptr;
37+
}
38+
OracleInterval& operator=(OracleInterval const& other)
39+
{
40+
lib_interval_tree::interval<numerical_type, interval_kind_>::operator=(other);
41+
oracle_ = other.oracle_;
42+
return *this;
43+
}
44+
OracleInterval& operator=(OracleInterval&& other)
45+
{
46+
lib_interval_tree::interval<numerical_type, interval_kind_>::operator=(other);
47+
oracle_ = other.oracle_;
48+
other.oracle_ = nullptr;
49+
return *this;
50+
}
51+
~OracleInterval()
52+
{
53+
if (oracle_ != nullptr)
54+
--oracle_->livingInstances;
55+
}
56+
OracleInterval join(OracleInterval const& other) const
57+
{
58+
return OracleInterval{oracle_, std::min(low_, other.low_), std::max(high_, other.high_)};
59+
}
60+
private:
61+
Oracle* oracle_;
62+
};
63+
64+
template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
65+
OracleInterval <numerical_type, interval_kind_> makeSafeOracleInterval(Oracle* oracle, numerical_type lhs, numerical_type rhs)
66+
{
67+
return OracleInterval <numerical_type, interval_kind_>{oracle, std::min(lhs, rhs), std::max(lhs, rhs)};
68+
}
669

770
class EraseTests
871
: public ::testing::Test
972
{
1073
public:
11-
using types = IntervalTypes <int>;
74+
using interval_type = OracleInterval<int>;
1275

1376
protected:
14-
IntervalTypes <int>::tree_type tree;
77+
Oracle oracle;
78+
lib_interval_tree::interval_tree <OracleInterval<int>> tree;
1579
std::default_random_engine gen;
1680
std::uniform_int_distribution <int> distSmall{-500, 500};
1781
std::uniform_int_distribution <int> distLarge{-50000, 50000};
1882
};
1983

2084
TEST_F(EraseTests, EraseSingleElement)
2185
{
22-
auto inserted_interval = types::interval_type{0, 16};
86+
auto inserted_interval = interval_type{&oracle, 0, 16};
2387

24-
tree.insert(inserted_interval);
88+
tree.insert(std::move(inserted_interval));
2589

90+
EXPECT_EQ(oracle.livingInstances, 1);
2691
tree.erase(tree.begin());
2792

93+
EXPECT_EQ(oracle.livingInstances, 0);
2894
EXPECT_EQ(tree.empty(), true);
2995
EXPECT_EQ(tree.size(), 0);
3096
}
@@ -34,11 +100,12 @@ TEST_F(EraseTests, ManualClearTest)
34100
constexpr int amount = 10'000;
35101

36102
for (int i = 0; i != amount; ++i)
37-
tree.insert(lib_interval_tree::make_safe_interval(distSmall(gen), distSmall(gen)));
103+
tree.insert(makeSafeOracleInterval(&oracle, distSmall(gen), distSmall(gen)));
38104

39105
for (auto i = std::begin(tree); i != std::end(tree);)
40106
i = tree.erase(i);
41107

108+
EXPECT_EQ(oracle.livingInstances, 0);
42109
EXPECT_EQ(tree.empty(), true);
43110
}
44111

@@ -47,20 +114,39 @@ TEST_F(EraseTests, ClearTest)
47114
constexpr int amount = 10'000;
48115

49116
for (int i = 0; i != amount; ++i)
50-
tree.insert(lib_interval_tree::make_safe_interval(distSmall(gen), distSmall(gen)));
117+
tree.insert(makeSafeOracleInterval(&oracle, distSmall(gen), distSmall(gen)));
51118

52119
tree.clear();
53120

121+
EXPECT_EQ(oracle.livingInstances, 0);
54122
EXPECT_EQ(tree.empty(), true);
55123
}
56124

125+
TEST_F(EraseTests, ExpectedElementIsDeleted)
126+
{
127+
tree.insert(makeSafeOracleInterval(&oracle, 16, 21));
128+
tree.insert(makeSafeOracleInterval(&oracle, 8, 9));
129+
tree.insert(makeSafeOracleInterval(&oracle, 25, 30));
130+
tree.insert(makeSafeOracleInterval(&oracle, 5, 8));
131+
tree.insert(makeSafeOracleInterval(&oracle, 15, 23));
132+
tree.insert(makeSafeOracleInterval(&oracle, 17, 19));
133+
tree.insert(makeSafeOracleInterval(&oracle, 26, 26));
134+
tree.insert(makeSafeOracleInterval(&oracle, 0, 3));
135+
tree.insert(makeSafeOracleInterval(&oracle, 6, 10));
136+
tree.insert(makeSafeOracleInterval(&oracle, 19, 20));
137+
138+
tree.erase(tree.find(makeSafeOracleInterval(&oracle, 17, 19)));
139+
EXPECT_EQ(tree.find(makeSafeOracleInterval(&oracle, 17, 19)), tree.end());
140+
EXPECT_EQ(tree.size(), 9);
141+
}
142+
57143
TEST_F(EraseTests, RandomEraseTest)
58144
{
59145
constexpr int amount = 10'000;
60-
constexpr int deleteAmount = 20;
146+
constexpr int deleteAmount = 50;
61147

62148
for (int i = 0; i != amount; ++i)
63-
tree.insert(lib_interval_tree::make_safe_interval(distSmall(gen), distSmall(gen)));
149+
tree.insert(makeSafeOracleInterval(&oracle, distSmall(gen), distSmall(gen)));
64150

65151
for (int i = 0; i != deleteAmount; ++i)
66152
{
@@ -69,9 +155,10 @@ TEST_F(EraseTests, RandomEraseTest)
69155
auto iter = tree.begin();
70156
for (int j = 0; j != end; ++j)
71157
++iter;
158+
tree.erase(iter);
72159
}
73160

161+
EXPECT_EQ(oracle.livingInstances, amount - deleteAmount);
74162
testMaxProperty(tree);
75-
testRedBlackPropertyViolation(tree);
76163
testTreeHeightHealth(tree);
77164
}

tests/interval_tests.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ TEST_F(IntervalTests, FailBadBorders)
3434
{
3535
auto f = []()
3636
{
37-
[[maybe_unused]] auto ival = types::interval_type{1, 0};
37+
#if __cplusplus >= 201703L
38+
[[maybe_unused]]
39+
#endif
40+
auto ival = types::interval_type{1, 0};
3841
};
3942

4043
ASSERT_THROW(f(), std::invalid_argument);

0 commit comments

Comments
 (0)