result_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <string>
  6. #include "remoting/base/result.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. namespace remoting {
  9. TEST(Result, DefaultConstruction) {
  10. struct DefaultConstruct {
  11. std::string value;
  12. DefaultConstruct() : value("value1") {}
  13. };
  14. Result<DefaultConstruct, int> result;
  15. ASSERT_TRUE(result.is_success());
  16. EXPECT_EQ("value1", result.success().value);
  17. }
  18. namespace {
  19. struct NotDefaultConstructible {
  20. NotDefaultConstructible(int);
  21. };
  22. } // namespace
  23. static_assert(
  24. !std::is_default_constructible<Result<NotDefaultConstructible, int>>::value,
  25. "Should not be default constructible if success type isn't.");
  26. TEST(Result, TaggedSuccessConstruction) {
  27. Result<std::string, int> result(kSuccessTag, 5, 'a');
  28. ASSERT_TRUE(result.is_success());
  29. ASSERT_FALSE(result.is_error());
  30. EXPECT_EQ("aaaaa", result.success());
  31. }
  32. TEST(Result, TaggedErrorConstruction) {
  33. Result<std::string, int> result(kErrorTag, 2);
  34. ASSERT_FALSE(result.is_success());
  35. ASSERT_TRUE(result.is_error());
  36. EXPECT_EQ(2, result.error());
  37. }
  38. static_assert(
  39. !std::is_constructible<Result<std::string, int>, SuccessTag, float>::value,
  40. "Invalid constructor parameters should trigger SFINAE.");
  41. TEST(Result, ImplicitSuccessConstruction) {
  42. Result<std::string, int> result = "value3";
  43. ASSERT_TRUE(result.is_success());
  44. EXPECT_EQ("value3", result.success());
  45. }
  46. TEST(Result, ImplicitErrorConstruction) {
  47. Result<std::string, int> result = 3;
  48. ASSERT_TRUE(result.is_error());
  49. EXPECT_EQ(3, result.error());
  50. }
  51. static_assert(!std::is_constructible<Result<int, float>, int>::value,
  52. "Should not allow ambiguous untagged construction.");
  53. TEST(Result, SuccessCopyConstruction) {
  54. Result<std::string, int> result1 = "value4";
  55. Result<std::string, int> result2 = result1;
  56. ASSERT_TRUE(result2.is_success());
  57. EXPECT_EQ("value4", result2.success());
  58. // Ensure result1 wasn't modified.
  59. EXPECT_EQ("value4", result1.success());
  60. }
  61. TEST(Result, ErrorCopyConstruction) {
  62. Result<int, std::string> result1 = "value5";
  63. Result<int, std::string> result2 = result1;
  64. ASSERT_TRUE(result2.is_error());
  65. EXPECT_EQ("value5", result2.error());
  66. // Ensure result1 wasn't modified.
  67. EXPECT_EQ("value5", result1.error());
  68. }
  69. static_assert(
  70. !std::is_copy_constructible<Result<std::unique_ptr<int>, int>>::value &&
  71. !std::is_copy_constructible<Result<int, std::unique_ptr<int>>>::value,
  72. "Should not be copy constructible if either type isn't.");
  73. TEST(Result, SuccessMoveConstruction) {
  74. Result<std::unique_ptr<std::string>, int> result1 =
  75. std::make_unique<std::string>("value6");
  76. Result<std::unique_ptr<std::string>, int> result2 = std::move(result1);
  77. ASSERT_TRUE(result2.is_success());
  78. EXPECT_EQ("value6", *result2.success());
  79. EXPECT_TRUE(result1.is_success());
  80. EXPECT_FALSE(result1.success());
  81. }
  82. TEST(Result, ErrorMoveConstruction) {
  83. Result<int, std::unique_ptr<std::string>> result1 =
  84. std::make_unique<std::string>("value7");
  85. Result<int, std::unique_ptr<std::string>> result2 = std::move(result1);
  86. ASSERT_TRUE(result2.is_error());
  87. EXPECT_EQ("value7", *result2.error());
  88. EXPECT_TRUE(result1.is_error());
  89. EXPECT_FALSE(result1.error());
  90. }
  91. TEST(Result, SuccessCopyConversion) {
  92. const char* value = "value8";
  93. Result<const char*, int> result1 = value;
  94. Result<std::string, int> result2 = result1;
  95. ASSERT_TRUE(result2.is_success());
  96. EXPECT_EQ("value8", result2.success());
  97. EXPECT_EQ(value, result1.success());
  98. }
  99. TEST(Result, ErrorCopyConversion) {
  100. const char* value = "value9";
  101. Result<int, const char*> result1 = value;
  102. Result<int, std::string> result2 = result1;
  103. ASSERT_TRUE(result2.is_error());
  104. EXPECT_EQ("value9", result2.error());
  105. EXPECT_EQ(value, result1.error());
  106. }
  107. TEST(Result, SuccessMoveConversion) {
  108. struct Deleter {
  109. Deleter(const std::default_delete<std::string>&) {}
  110. void operator()(void* ptr) { delete static_cast<std::string*>(ptr); }
  111. };
  112. Result<std::unique_ptr<std::string>, int> result1 =
  113. std::make_unique<std::string>("value10");
  114. Result<std::unique_ptr<void, Deleter>, int> result2 = std::move(result1);
  115. ASSERT_TRUE(result2.is_success());
  116. EXPECT_EQ("value10", *static_cast<std::string*>(result2.success().get()));
  117. }
  118. TEST(Result, ErrorMoveConversion) {
  119. struct Deleter {
  120. Deleter(const std::default_delete<std::string>&) {}
  121. void operator()(void* ptr) { delete static_cast<std::string*>(ptr); }
  122. };
  123. Result<int, std::unique_ptr<std::string>> result1 =
  124. std::make_unique<std::string>("value11");
  125. Result<int, std::unique_ptr<void, Deleter>> result2 = std::move(result1);
  126. ASSERT_TRUE(result2.is_error());
  127. EXPECT_EQ("value11", *static_cast<std::string*>(result2.error().get()));
  128. }
  129. TEST(Result, Destruction) {
  130. class DestructIncrement {
  131. public:
  132. explicit DestructIncrement(int* variable) : variable_(variable) {}
  133. ~DestructIncrement() { ++(*variable_); }
  134. private:
  135. int* variable_;
  136. };
  137. int success_count = 0;
  138. int error_count = 0;
  139. Result<DestructIncrement, int>(kSuccessTag, &success_count);
  140. EXPECT_EQ(1, success_count);
  141. EXPECT_EQ(0, error_count);
  142. Result<int, DestructIncrement>(kErrorTag, &error_count);
  143. EXPECT_EQ(1, success_count);
  144. EXPECT_EQ(1, error_count);
  145. }
  146. TEST(Result, CopyAssignment) {
  147. Result<std::string, int> result1 = "value12";
  148. Result<std::string, int> result2 = 0;
  149. result2 = result1;
  150. ASSERT_TRUE(result2.is_success());
  151. EXPECT_EQ("value12", result2.success());
  152. static_assert(
  153. !std::is_copy_assignable<Result<std::unique_ptr<int>, int>>::value &&
  154. !std::is_copy_assignable<Result<int, std::unique_ptr<int>>>::value,
  155. "Should not be copy assignable if either type isn't.");
  156. }
  157. TEST(Result, MoveAssignment) {
  158. Result<std::unique_ptr<std::string>, int> result1 =
  159. std::make_unique<std::string>("value13");
  160. Result<std::unique_ptr<std::string>, int> result2 = 0;
  161. result2 = std::move(result1);
  162. ASSERT_TRUE(result2.is_success());
  163. EXPECT_EQ("value13", *result2.success());
  164. }
  165. TEST(Result, CopyConversionAssignment) {
  166. const char* value1 = "value14";
  167. Result<const char*, int> result1 = value1;
  168. Result<std::string, int> result2 = 0;
  169. result2 = result1;
  170. ASSERT_TRUE(result2.is_success());
  171. EXPECT_EQ("value14", result2.success());
  172. }
  173. TEST(Result, MoveConversionAssignment) {
  174. struct Deleter {
  175. Deleter(const std::default_delete<std::string>&) {}
  176. void operator()(void* ptr) { delete static_cast<std::string*>(ptr); }
  177. };
  178. Result<std::unique_ptr<std::string>, int> result1 =
  179. std::make_unique<std::string>("value15");
  180. Result<std::unique_ptr<void, Deleter>, int> result2 = 0;
  181. result2 = std::move(result1);
  182. ASSERT_TRUE(result2.is_success());
  183. EXPECT_EQ("value15", *static_cast<std::string*>(result2.success().get()));
  184. }
  185. TEST(Result, EmplaceSuccess) {
  186. Result<std::string, int> result = 0;
  187. result.EmplaceSuccess(5, 'p');
  188. ASSERT_TRUE(result.is_success());
  189. EXPECT_EQ("ppppp", result.success());
  190. }
  191. TEST(Result, EmplaceError) {
  192. Result<std::string, int> result;
  193. result.EmplaceError(17);
  194. ASSERT_TRUE(result.is_error());
  195. EXPECT_EQ(17, result.error());
  196. }
  197. TEST(Result, MapLvalue) {
  198. Result<std::string, int> result1 = "value18";
  199. Result<const char*, int> result2 =
  200. result1.Map([](const std::string& value) { return value.c_str(); });
  201. ASSERT_TRUE(result2.is_success());
  202. EXPECT_TRUE(strcmp("value18", result2.success()) == 0);
  203. }
  204. TEST(Result, MapRvalue) {
  205. Result<std::unique_ptr<std::string>, int> result1 =
  206. std::make_unique<std::string>("value19");
  207. auto result2 = std::move(result1).Map(
  208. [](std::unique_ptr<std::string>&& value) { return std::move(*value); });
  209. static_assert(
  210. std::is_same<decltype(result2), Result<std::string, int>>::value,
  211. "Incorrect type inferred.");
  212. ASSERT_TRUE(result2.is_success());
  213. EXPECT_EQ("value19", result2.success());
  214. }
  215. TEST(Result, MapPassesErrorThrough) {
  216. Result<std::string, int> result1 = 20;
  217. Result<const char*, int> result2 =
  218. result1.Map([](const std::string& value) { return value.c_str(); });
  219. ASSERT_TRUE(result2.is_error());
  220. EXPECT_EQ(20, result2.error());
  221. }
  222. TEST(Result, MapErrorLvalue) {
  223. Result<std::string, int> result1 = 21;
  224. Result<std::string, int> result2 =
  225. result1.MapError([](int value) { return value + 1; });
  226. ASSERT_TRUE(result2.is_error());
  227. EXPECT_EQ(22, result2.error());
  228. }
  229. TEST(Result, MapErrorRvalue) {
  230. Result<int, std::unique_ptr<std::string>> result1 =
  231. std::make_unique<std::string>("value23");
  232. auto result2 =
  233. std::move(result1).MapError([](std::unique_ptr<std::string>&& value) {
  234. return std::make_unique<std::size_t>(value->size());
  235. });
  236. static_assert(std::is_same<decltype(result2),
  237. Result<int, std::unique_ptr<std::size_t>>>::value,
  238. "Incorrect type inferred.");
  239. ASSERT_TRUE(result2.is_error());
  240. EXPECT_EQ(7UL, *result2.error());
  241. }
  242. TEST(Result, MapErrorPassesSuccessThrough) {
  243. Result<std::string, int> result1 = "value24";
  244. Result<std::string, float> result2 =
  245. result1.MapError([](int value) { return value * 2.0; });
  246. ASSERT_TRUE(result2.is_success());
  247. EXPECT_EQ("value24", result2.success());
  248. }
  249. TEST(Result, AndThenLvalue) {
  250. Result<std::string, int> result1 = "value25";
  251. auto result2 = result1.AndThen(
  252. [](const std::string&) { return Result<const char*, float>(26.0); });
  253. static_assert(
  254. std::is_same<decltype(result2), Result<const char*, int>>::value,
  255. "Error type should stay the same.");
  256. ASSERT_TRUE(result2.is_error());
  257. EXPECT_EQ(26, result2.error());
  258. }
  259. TEST(Result, AndThenRvalue) {
  260. Result<std::unique_ptr<std::string>, int> result1 =
  261. std::make_unique<std::string>("value27");
  262. auto result2 =
  263. std::move(result1).AndThen([](std::unique_ptr<std::string>&& value) {
  264. return Result<std::string, int>(std::move(*value));
  265. });
  266. static_assert(
  267. std::is_same<decltype(result2), Result<std::string, int>>::value,
  268. "Incorrect type inferred.");
  269. ASSERT_TRUE(result2.is_success());
  270. EXPECT_EQ("value27", result2.success());
  271. }
  272. TEST(Result, AndThenPassesErrorThrough) {
  273. Result<std::string, int> result1 = 28;
  274. Result<int, int> result2 = result1.AndThen(
  275. [](const std::string&) { return Result<int, int>(kSuccessTag, 29); });
  276. ASSERT_TRUE(result2.is_error());
  277. EXPECT_EQ(28, result2.error());
  278. }
  279. TEST(Result, OrElseLvalue) {
  280. Result<std::string, int> result1 = 30;
  281. Result<std::string, int> result2 =
  282. result1.OrElse([](int) -> Result<std::string, int> { return "value31"; });
  283. ASSERT_TRUE(result2.is_success());
  284. EXPECT_EQ("value31", result2.success());
  285. }
  286. TEST(Result, OrElseRvalue) {
  287. Result<int, std::unique_ptr<std::string>> result1 =
  288. std::make_unique<std::string>("value32");
  289. Result<int, std::string> result2 =
  290. std::move(result1).OrElse([](std::unique_ptr<std::string>&&) {
  291. return Result<int, std::string>("value33");
  292. });
  293. ASSERT_TRUE(result2.is_error());
  294. EXPECT_EQ("value33", result2.error());
  295. }
  296. TEST(Result, OrElsePassesSuccessThrough) {
  297. Result<std::string, int> result1 = "value34";
  298. Result<std::string, float> result2 = result1.OrElse(
  299. [](int value) -> Result<std::string, float> { return value * 2.0; });
  300. ASSERT_TRUE(result2.is_success());
  301. EXPECT_EQ("value34", result2.success());
  302. }
  303. TEST(Result, Visit) {
  304. struct Visitor {
  305. char success(const std::string& value) {
  306. EXPECT_EQ("value35", value);
  307. return '\1';
  308. }
  309. bool success(std::string& value) {
  310. EXPECT_EQ("value35", value);
  311. return true;
  312. }
  313. int success(std::string&& value) {
  314. EXPECT_EQ("value35", value);
  315. return 1;
  316. }
  317. char error(const std::wstring& value) {
  318. EXPECT_EQ(L"value36", value);
  319. return '\0';
  320. }
  321. bool error(std::wstring& value) {
  322. EXPECT_EQ(L"value36", value);
  323. return false;
  324. }
  325. int error(std::wstring&& value) {
  326. EXPECT_EQ(L"value36", value);
  327. return 0;
  328. }
  329. };
  330. Result<std::string, std::wstring> result;
  331. result.EmplaceSuccess("value35");
  332. auto success1 =
  333. const_cast<const Result<std::string, std::wstring>&>(result).Visit(
  334. Visitor());
  335. static_assert(std::is_same<char, decltype(success1)>::value,
  336. "Return type should be char.");
  337. EXPECT_EQ('\1', success1);
  338. auto success2 = result.Visit(Visitor());
  339. static_assert(std::is_same<bool, decltype(success2)>::value,
  340. "Return type should be bool.");
  341. EXPECT_EQ(true, success2);
  342. auto success3 = std::move(result).Visit(Visitor());
  343. static_assert(std::is_same<int, decltype(success3)>::value,
  344. "Return type should be int.");
  345. EXPECT_EQ(1, success3);
  346. result.EmplaceError(L"value36");
  347. auto error1 =
  348. const_cast<const Result<std::string, std::wstring>&>(result).Visit(
  349. Visitor());
  350. EXPECT_EQ('\0', error1);
  351. auto error2 = result.Visit(Visitor());
  352. EXPECT_EQ(false, error2);
  353. auto error3 = std::move(result).Visit(Visitor());
  354. EXPECT_EQ(0, error3);
  355. }
  356. } // namespace remoting