blob: b3ba6a62e6df688f7246714d74a1368d4ed7c269 [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);
51 h.reset();
52 EXPECT_FALSE(h.has_value());
53 EXPECT_THROW(h.value(), std::bad_optional_access);
54 EXPECT_EQ(std::nullopt, h.maybe_value());
55}
56
57TEST_F(ManagedHandleTest, EmptyWithStorage)
58{
59 StoreHandle h(std::nullopt, "str", 5);
60 EXPECT_FALSE(h);
61 EXPECT_THROW(h.value(), std::bad_optional_access);
62 h.reset(std::nullopt);
63 EXPECT_FALSE(h);
64 EXPECT_THROW(h.value(), std::bad_optional_access);
65
66 StoreHandle h2(std::nullopt, std::make_tuple<std::string, int>("str", 5));
67 EXPECT_FALSE(h2);
68 EXPECT_THROW(h2.value(), std::bad_optional_access);
69}
70
71TEST_F(ManagedHandleTest, SimplePopulated)
72{
73 constexpr int expected = 3;
74 {
75 int val = expected;
76 SimpleHandle h(std::move(val));
77 EXPECT_TRUE(h.has_value());
78 EXPECT_EQ(expected, *h);
79 EXPECT_EQ(expected, h.value());
80 EXPECT_EQ(expected, h.maybe_value());
81 EXPECT_TRUE(dropped.empty());
82 }
83 EXPECT_EQ(std::vector{expected}, dropped);
84 dropped.clear();
85}
86
87TEST_F(ManagedHandleTest, OptionalPopulated)
88{
89 constexpr int expected = 3;
90 {
91 std::optional<int> maybeVal{expected};
92 SimpleHandle h(std::move(maybeVal));
93 EXPECT_TRUE(h);
94 EXPECT_EQ(expected, *h);
95 EXPECT_EQ(expected, h.value());
96 EXPECT_TRUE(dropped.empty());
97 }
98 EXPECT_EQ(std::vector{expected}, dropped);
99 dropped.clear();
100}
101
102TEST_F(ManagedHandleTest, SimplePopulatedWithStorage)
103{
104 constexpr int expected = 3;
105 {
106 StoreHandle h(int{expected}, std::make_tuple(std::string{"str"}, 5));
107 EXPECT_TRUE(h);
108 EXPECT_EQ(expected, *h);
109 EXPECT_EQ(expected, h.value());
110 EXPECT_TRUE(dropped.empty());
111 }
112 EXPECT_EQ(5, stored);
113 EXPECT_EQ(std::vector{expected}, dropped);
114 dropped.clear();
115}
116
117TEST_F(ManagedHandleTest, ResetPopulatedWithStorage)
118{
119 constexpr int expected = 3;
120 const std::string s{"str"};
121 StoreHandle h(int{expected}, s, 5);
122 EXPECT_TRUE(dropped.empty());
123 h.reset(std::nullopt);
124 EXPECT_FALSE(h);
125 EXPECT_THROW(h.value(), std::bad_optional_access);
126 EXPECT_EQ(5, stored);
127 EXPECT_EQ(std::vector{expected}, dropped);
128 dropped.clear();
129}
130
131TEST_F(ManagedHandleTest, ResetNewPopulated)
132{
133 constexpr int expected = 3, expected2 = 10;
134 {
135 SimpleHandle h(int{expected});
136 EXPECT_TRUE(dropped.empty());
137 h.reset(int{expected2});
138 EXPECT_TRUE(h);
139 EXPECT_EQ(expected2, *h);
140 EXPECT_EQ(expected2, h.value());
141 EXPECT_EQ(std::vector{expected}, dropped);
142 dropped.clear();
143 }
144 EXPECT_EQ(std::vector{expected2}, dropped);
145 dropped.clear();
146}
147
148TEST_F(ManagedHandleTest, ResetNewPopulatedWithStorage)
149{
150 constexpr int expected = 3, expected2 = 10;
151 {
152 StoreHandle h(int{expected}, "str", 5);
153 EXPECT_TRUE(dropped.empty());
154 h.reset(int{expected2});
155 EXPECT_TRUE(h);
156 EXPECT_EQ(expected2, *h);
157 EXPECT_EQ(expected2, h.value());
158 EXPECT_EQ(5, stored);
159 EXPECT_EQ(std::vector{expected}, dropped);
160 dropped.clear();
161 }
162 EXPECT_EQ(6, stored);
163 EXPECT_EQ(std::vector{expected2}, dropped);
164 dropped.clear();
165}
166
167TEST_F(ManagedHandleTest, MoveConstructWithStorage)
168{
169 constexpr int expected = 3;
170 StoreHandle h1(int{expected}, "str", 5);
171 {
172 StoreHandle h2(std::move(h1));
173 EXPECT_TRUE(dropped.empty());
174 EXPECT_FALSE(h1);
175 EXPECT_THROW(h1.value(), std::bad_optional_access);
176 EXPECT_TRUE(h2);
177 EXPECT_EQ(expected, *h2);
178 EXPECT_EQ(expected, h2.value());
179 }
180 EXPECT_EQ(5, stored);
181 EXPECT_EQ(std::vector{expected}, dropped);
182 dropped.clear();
183}
184
185TEST_F(ManagedHandleTest, MoveAssignWithStorage)
186{
187 constexpr int expected = 3, expected2 = 10;
188 {
189 StoreHandle h1(int{expected}, "str", 5);
190 StoreHandle h2(int{expected2}, "str", 10);
191 EXPECT_TRUE(dropped.empty());
192
193 h2 = std::move(h1);
194 EXPECT_EQ(10, stored);
195 EXPECT_EQ(std::vector{expected2}, dropped);
196 dropped.clear();
197 EXPECT_FALSE(h1);
198 EXPECT_THROW(h1.value(), std::bad_optional_access);
199 EXPECT_TRUE(h2);
200 EXPECT_EQ(expected, *h2);
201 EXPECT_EQ(expected, h2.value());
202 }
203 EXPECT_EQ(5, stored);
204 EXPECT_EQ(std::vector{expected}, dropped);
205 dropped.clear();
206}
207
208} // namespace
209} // namespace stdplus