Fix the linking of various tests against GMock
[folly.git] / folly / test / OverloadTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #include <boost/variant.hpp>
17 #include <folly/DiscriminatedPtr.h>
18 #include <folly/Overload.h>
19 #include <folly/portability/GTest.h>
20
21 namespace folly {
22 namespace test {
23
24 struct One {
25   std::string toString() const {
26     return "One";
27   }
28 };
29 struct Two {
30   std::string toString() const {
31     return "Two";
32   }
33 };
34 using OneOrTwo = boost::variant<One, Two>;
35
36 TEST(Overload, BoostVariant) {
37   OneOrTwo one(One{});
38   OneOrTwo two(Two{});
39
40   EXPECT_TRUE(variant_match(
41       one, [](const One&) { return true; }, [](const Two&) { return false; }));
42   EXPECT_TRUE(variant_match(
43       two, [](const One&) { return false; }, [](const Two&) { return true; }));
44
45   auto toString = [](const auto& variant) {
46     return variant_match(
47         variant, [](const auto& value) { return value.toString(); });
48   };
49   EXPECT_EQ(toString(one), "One");
50   EXPECT_EQ(toString(two), "Two");
51 }
52
53 TEST(Overload, DiscriminatedPtr) {
54   using V = DiscriminatedPtr<One, Two>;
55   One one_obj;
56   Two two_obj;
57   V one_ptr(&one_obj);
58   V two_ptr(&two_obj);
59
60   EXPECT_TRUE(variant_match(
61       one_ptr,
62       [](const One*) { return true; },
63       [](const Two*) { return false; }));
64   EXPECT_TRUE(variant_match(
65       two_ptr,
66       [](const One*) { return false; },
67       [](const Two*) { return true; }));
68
69   auto toString = [](const auto& variant) {
70     return variant_match(
71         variant, [](const auto* value) { return value->toString(); });
72   };
73   EXPECT_EQ(toString(one_ptr), "One");
74   EXPECT_EQ(toString(two_ptr), "Two");
75 }
76
77 TEST(Overload, Pattern) {
78   OneOrTwo one(One{});
79   OneOrTwo two(Two{});
80
81   auto is_one_overload = overload(
82       [](const One&) { return true; }, [](const Two&) { return false; });
83   EXPECT_TRUE(boost::apply_visitor(is_one_overload, one));
84   EXPECT_TRUE(variant_match(one, is_one_overload));
85   EXPECT_FALSE(variant_match(two, is_one_overload));
86
87   auto is_two_overload = overload(
88       [](const One&) { return false; }, [](const Two&) { return true; });
89   EXPECT_TRUE(boost::apply_visitor(is_two_overload, two));
90   EXPECT_FALSE(variant_match(one, is_two_overload));
91   EXPECT_TRUE(variant_match(two, is_two_overload));
92
93   auto is_one_copy = overload(is_one_overload);
94   auto is_one_const_copy =
95       overload(static_cast<const decltype(is_one_overload)&>(is_one_overload));
96   EXPECT_TRUE(variant_match(one, is_one_copy));
97   EXPECT_TRUE(variant_match(one, is_one_const_copy));
98   EXPECT_FALSE(variant_match(two, is_one_copy));
99   EXPECT_FALSE(variant_match(two, is_one_const_copy));
100 }
101 }
102 } // folly::test