blob: 155ba596b8cf712f3db0bbdbb2500d0a4a5ff6e4 [file] [log] [blame]
William A. Kennington III7a5e2322018-11-02 17:28:35 -07001#include <gtest/gtest.h>
2#include <optional>
3#include <stdplus/handle/managed.hpp>
4#include <string>
5#include <tuple>
6#include <utility>
7#include <vector>
8
9namespace stdplus
10{
11namespace
12{
13
14static std::vector<int> dropped;
15static int stored = 0;
16
17void drop(int&& i)
18{
19 dropped.push_back(std::move(i));
20}
21
22void drop(int&& i, std::string&, int& si)
23{
24 dropped.push_back(std::move(i));
25 // Make sure we can update the stored data
26 stored = si++;
27}
28
29using SimpleHandle = Managed<int>::Handle<drop>;
30using StoreHandle = Managed<int, std::string, int>::Handle<drop>;
31
32class ManagedHandleTest : public ::testing::Test
33{
34 protected:
35 void SetUp()
36 {
37 dropped.clear();
38 }
39
40 void TearDown()
41 {
42 EXPECT_TRUE(dropped.empty());
43 }
44};
45
46TEST_F(ManagedHandleTest, EmptyNoStorage)
47{
48 SimpleHandle h(std::nullopt);
49 EXPECT_FALSE(h);
50 EXPECT_THROW(h.value(), std::bad_optional_access);
William A. Kennington III079cba72019-07-01 17:28:32 -070051 EXPECT_THROW((void)h.release(), std::bad_optional_access);
William A. Kennington III7a5e2322018-11-02 17:28:35 -070052 h.reset();
53 EXPECT_FALSE(h.has_value());
54 EXPECT_THROW(h.value(), std::bad_optional_access);
William A. Kennington III079cba72019-07-01 17:28:32 -070055 EXPECT_THROW((void)h.release(), std::bad_optional_access);
William A. Kennington III7a5e2322018-11-02 17:28:35 -070056 EXPECT_EQ(std::nullopt, h.maybe_value());
William A. Kennington III079cba72019-07-01 17:28:32 -070057 EXPECT_EQ(std::nullopt, h.maybe_release());
William A. Kennington III7a5e2322018-11-02 17:28:35 -070058}
59
60TEST_F(ManagedHandleTest, EmptyWithStorage)
61{
62 StoreHandle h(std::nullopt, "str", 5);
63 EXPECT_FALSE(h);
64 EXPECT_THROW(h.value(), std::bad_optional_access);
65 h.reset(std::nullopt);
66 EXPECT_FALSE(h);
67 EXPECT_THROW(h.value(), std::bad_optional_access);
68
69 StoreHandle h2(std::nullopt, std::make_tuple<std::string, int>("str", 5));
70 EXPECT_FALSE(h2);
71 EXPECT_THROW(h2.value(), std::bad_optional_access);
72}
73
74TEST_F(ManagedHandleTest, SimplePopulated)
75{
76 constexpr int expected = 3;
77 {
78 int val = expected;
79 SimpleHandle h(std::move(val));
80 EXPECT_TRUE(h.has_value());
81 EXPECT_EQ(expected, *h);
82 EXPECT_EQ(expected, h.value());
83 EXPECT_EQ(expected, h.maybe_value());
84 EXPECT_TRUE(dropped.empty());
85 }
86 EXPECT_EQ(std::vector{expected}, dropped);
87 dropped.clear();
88}
89
90TEST_F(ManagedHandleTest, OptionalPopulated)
91{
92 constexpr int expected = 3;
93 {
94 std::optional<int> maybeVal{expected};
95 SimpleHandle h(std::move(maybeVal));
96 EXPECT_TRUE(h);
97 EXPECT_EQ(expected, *h);
98 EXPECT_EQ(expected, h.value());
99 EXPECT_TRUE(dropped.empty());
100 }
101 EXPECT_EQ(std::vector{expected}, dropped);
102 dropped.clear();
103}
104
105TEST_F(ManagedHandleTest, SimplePopulatedWithStorage)
106{
107 constexpr int expected = 3;
108 {
109 StoreHandle h(int{expected}, std::make_tuple(std::string{"str"}, 5));
110 EXPECT_TRUE(h);
111 EXPECT_EQ(expected, *h);
112 EXPECT_EQ(expected, h.value());
113 EXPECT_TRUE(dropped.empty());
114 }
115 EXPECT_EQ(5, stored);
116 EXPECT_EQ(std::vector{expected}, dropped);
117 dropped.clear();
118}
119
120TEST_F(ManagedHandleTest, ResetPopulatedWithStorage)
121{
122 constexpr int expected = 3;
123 const std::string s{"str"};
124 StoreHandle h(int{expected}, s, 5);
125 EXPECT_TRUE(dropped.empty());
126 h.reset(std::nullopt);
127 EXPECT_FALSE(h);
128 EXPECT_THROW(h.value(), std::bad_optional_access);
129 EXPECT_EQ(5, stored);
130 EXPECT_EQ(std::vector{expected}, dropped);
131 dropped.clear();
132}
133
134TEST_F(ManagedHandleTest, ResetNewPopulated)
135{
136 constexpr int expected = 3, expected2 = 10;
137 {
138 SimpleHandle h(int{expected});
139 EXPECT_TRUE(dropped.empty());
140 h.reset(int{expected2});
141 EXPECT_TRUE(h);
142 EXPECT_EQ(expected2, *h);
143 EXPECT_EQ(expected2, h.value());
144 EXPECT_EQ(std::vector{expected}, dropped);
145 dropped.clear();
146 }
147 EXPECT_EQ(std::vector{expected2}, dropped);
148 dropped.clear();
149}
150
151TEST_F(ManagedHandleTest, ResetNewPopulatedWithStorage)
152{
153 constexpr int expected = 3, expected2 = 10;
154 {
155 StoreHandle h(int{expected}, "str", 5);
156 EXPECT_TRUE(dropped.empty());
157 h.reset(int{expected2});
158 EXPECT_TRUE(h);
159 EXPECT_EQ(expected2, *h);
160 EXPECT_EQ(expected2, h.value());
161 EXPECT_EQ(5, stored);
162 EXPECT_EQ(std::vector{expected}, dropped);
163 dropped.clear();
164 }
165 EXPECT_EQ(6, stored);
166 EXPECT_EQ(std::vector{expected2}, dropped);
167 dropped.clear();
168}
169
William A. Kennington III079cba72019-07-01 17:28:32 -0700170TEST_F(ManagedHandleTest, Release)
171{
172 constexpr int expected = 3;
173 int val = expected;
174 SimpleHandle h(std::move(val));
175 EXPECT_EQ(expected, h.release());
176 EXPECT_FALSE(h);
177}
178
179TEST_F(ManagedHandleTest, MaybeRelease)
180{
181 constexpr int expected = 3;
182 int val = expected;
183 SimpleHandle h(std::move(val));
184 EXPECT_EQ(expected, h.maybe_release());
185 EXPECT_FALSE(h);
186}
187
William A. Kennington III7a5e2322018-11-02 17:28:35 -0700188TEST_F(ManagedHandleTest, MoveConstructWithStorage)
189{
190 constexpr int expected = 3;
191 StoreHandle h1(int{expected}, "str", 5);
192 {
193 StoreHandle h2(std::move(h1));
194 EXPECT_TRUE(dropped.empty());
195 EXPECT_FALSE(h1);
196 EXPECT_THROW(h1.value(), std::bad_optional_access);
197 EXPECT_TRUE(h2);
198 EXPECT_EQ(expected, *h2);
199 EXPECT_EQ(expected, h2.value());
200 }
201 EXPECT_EQ(5, stored);
202 EXPECT_EQ(std::vector{expected}, dropped);
203 dropped.clear();
204}
205
206TEST_F(ManagedHandleTest, MoveAssignWithStorage)
207{
208 constexpr int expected = 3, expected2 = 10;
209 {
210 StoreHandle h1(int{expected}, "str", 5);
211 StoreHandle h2(int{expected2}, "str", 10);
212 EXPECT_TRUE(dropped.empty());
213
214 h2 = std::move(h1);
215 EXPECT_EQ(10, stored);
216 EXPECT_EQ(std::vector{expected2}, dropped);
217 dropped.clear();
218 EXPECT_FALSE(h1);
219 EXPECT_THROW(h1.value(), std::bad_optional_access);
220 EXPECT_TRUE(h2);
221 EXPECT_EQ(expected, *h2);
222 EXPECT_EQ(expected, h2.value());
223 }
224 EXPECT_EQ(5, stored);
225 EXPECT_EQ(std::vector{expected}, dropped);
226 dropped.clear();
227}
228
229} // namespace
230} // namespace stdplus