2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/Try.h>
19 #include <glog/logging.h>
21 #include <folly/Memory.h>
22 #include <folly/Traits.h>
23 #include <folly/portability/GTest.h>
25 using namespace folly;
31 explicit A(int x) : x_(x) {}
43 Try<A> t_a(std::move(a));
47 EXPECT_EQ(5, t_a.value().x());
51 Try<A> t_a(in_place, 5);
53 EXPECT_EQ(5, t_a.value().x());
56 TEST(Try, in_place_nested) {
57 Try<Try<A>> t_t_a(in_place, in_place, 5);
59 EXPECT_EQ(5, t_t_a.value().value().x());
62 // Make sure we can copy Trys for copyable types
68 // But don't choke on move-only types
70 Try<std::unique_ptr<int>> t;
71 std::vector<Try<std::unique_ptr<int>>> v;
75 TEST(Try, makeTryWith) {
77 return std::make_unique<int>(1);
80 auto result = makeTryWith(func);
81 EXPECT_TRUE(result.hasValue());
82 EXPECT_EQ(*result.value(), 1);
85 TEST(Try, makeTryWithThrow) {
86 auto func = []() -> std::unique_ptr<int> {
87 throw std::runtime_error("Runtime");
90 auto result = makeTryWith(func);
91 EXPECT_TRUE(result.hasException<std::runtime_error>());
94 TEST(Try, makeTryWithVoid) {
99 auto result = makeTryWith(func);
100 EXPECT_TRUE(result.hasValue());
103 TEST(Try, makeTryWithVoidThrow) {
105 throw std::runtime_error("Runtime");
108 auto result = makeTryWith(func);
109 EXPECT_TRUE(result.hasException<std::runtime_error>());
112 template <typename E>
113 static E* get_exception(std::exception_ptr eptr) {
115 std::rethrow_exception(eptr);
123 TEST(Try, tryGetExceptionObject) {
124 auto epexn = std::make_exception_ptr(std::range_error("oops"));
125 auto epnum = std::make_exception_ptr(17);
127 auto exn = CHECK_NOTNULL(get_exception<std::range_error>(epexn));
128 auto num = CHECK_NOTNULL(get_exception<int>(epnum));
131 auto t = Try<bool>(true);
132 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
133 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
134 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
138 auto t = Try<bool>(exception_wrapper(epexn, *exn));
139 EXPECT_EQ(exn, t.tryGetExceptionObject());
140 EXPECT_EQ(exn, t.tryGetExceptionObject<std::runtime_error>());
141 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
145 auto t = Try<bool>(exception_wrapper(epnum, *num));
146 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
147 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
148 EXPECT_EQ(num, t.tryGetExceptionObject<int>());
152 auto t = Try<void>();
153 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
154 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
155 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
159 auto t = Try<void>(exception_wrapper(epexn, *exn));
160 EXPECT_EQ(exn, t.tryGetExceptionObject());
161 EXPECT_EQ(exn, t.tryGetExceptionObject<std::runtime_error>());
162 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
166 auto t = Try<void>(exception_wrapper(epnum, *num));
167 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
168 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
169 EXPECT_EQ(num, t.tryGetExceptionObject<int>());
173 auto const t = Try<bool>(true);
174 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
175 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
176 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
180 auto const t = Try<bool>(exception_wrapper(epexn, *exn));
181 EXPECT_EQ(exn, t.tryGetExceptionObject());
182 EXPECT_EQ(exn, t.tryGetExceptionObject<std::runtime_error>());
183 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
187 auto const t = Try<bool>(exception_wrapper(epnum, *num));
188 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
189 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
190 EXPECT_EQ(num, t.tryGetExceptionObject<int>());
194 auto const t = Try<void>();
195 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
196 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
197 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
201 auto const t = Try<void>(exception_wrapper(epexn, *exn));
202 EXPECT_EQ(exn, t.tryGetExceptionObject());
203 EXPECT_EQ(exn, t.tryGetExceptionObject<std::runtime_error>());
204 EXPECT_EQ(nullptr, t.tryGetExceptionObject<int>());
208 auto const t = Try<void>(exception_wrapper(epnum, *num));
209 EXPECT_EQ(nullptr, t.tryGetExceptionObject());
210 EXPECT_EQ(nullptr, t.tryGetExceptionObject<std::runtime_error>());
211 EXPECT_EQ(num, t.tryGetExceptionObject<int>());
215 TEST(Try, withException) {
216 auto ew = make_exception_wrapper<std::range_error>("oops");
219 auto t = Try<bool>(true);
220 EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
221 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
222 EXPECT_FALSE(t.withException([](std::runtime_error&) {}));
223 EXPECT_FALSE(t.withException([](std::logic_error&) {}));
227 auto t = Try<bool>(ew);
228 EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
229 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
230 EXPECT_TRUE(t.withException([](std::runtime_error&) {}));
231 EXPECT_FALSE(t.withException([](std::logic_error&) {}));
235 auto t = Try<void>();
236 EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
237 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
238 EXPECT_FALSE(t.withException([](std::runtime_error&) {}));
239 EXPECT_FALSE(t.withException([](std::logic_error&) {}));
243 auto t = Try<void>(ew);
244 EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
245 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
246 EXPECT_TRUE(t.withException([](std::runtime_error&) {}));
247 EXPECT_FALSE(t.withException([](std::logic_error&) {}));
251 auto const t = Try<bool>(true);
252 EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
253 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
254 EXPECT_FALSE(t.withException([](std::runtime_error const&) {}));
255 EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
259 auto const t = Try<bool>(ew);
260 EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
261 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
262 EXPECT_TRUE(t.withException([](std::runtime_error const&) {}));
263 EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
267 auto const t = Try<void>();
268 EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
269 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
270 EXPECT_FALSE(t.withException([](std::runtime_error const&) {}));
271 EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
275 auto const t = Try<void>(ew);
276 EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
277 EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
278 EXPECT_TRUE(t.withException([](std::runtime_error const&) {}));
279 EXPECT_FALSE(t.withException([](std::logic_error const&) {}));