xref: /aosp_15_r20/external/cronet/base/traits_bag_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/traits_bag.h"
6 
7 #include <optional>
8 
9 #include "testing/gmock/include/gmock/gmock.h"
10 
11 namespace base {
12 namespace trait_helpers {
13 namespace {
14 
15 struct ExampleTrait {};
16 
17 struct ExampleTrait2 {};
18 
19 enum class EnumTraitA { A, B, C };
20 
21 enum class EnumTraitB { ONE, TWO };
22 
23 struct TestTraits {
24   // List of traits that are valid inputs for the constructor below.
25   struct ValidTrait {
26     ValidTrait(ExampleTrait);
27     ValidTrait(EnumTraitA);
28     ValidTrait(EnumTraitB);
29   };
30 
31   template <class... ArgTypes>
32     requires trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>
TestTraitsbase::trait_helpers::__anonffaff87e0111::TestTraits33   constexpr TestTraits(ArgTypes... args)
34       : has_example_trait(trait_helpers::HasTrait<ExampleTrait, ArgTypes...>()),
35         enum_trait_a(
36             trait_helpers::GetEnum<EnumTraitA, EnumTraitA::A>(args...)),
37         enum_trait_b(
38             trait_helpers::GetEnum<EnumTraitB, EnumTraitB::ONE>(args...)) {}
39 
40   const bool has_example_trait;
41   const EnumTraitA enum_trait_a;
42   const EnumTraitB enum_trait_b;
43 };
44 
45 // Like TestTraits, except ExampleTrait is filtered away.
46 struct FilteredTestTraits : public TestTraits {
47   template <class... ArgTypes>
48     requires trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>
FilteredTestTraitsbase::trait_helpers::__anonffaff87e0111::FilteredTestTraits49   constexpr FilteredTestTraits(ArgTypes... args)
50       : TestTraits(Exclude<ExampleTrait>::Filter(args)...) {}
51 };
52 
53 struct RequiredEnumTestTraits {
54   // List of traits that are required inputs for the constructor below.
55   struct ValidTrait {
56     ValidTrait(EnumTraitA);
57   };
58 
59   // We require EnumTraitA to be specified.
60   template <class... ArgTypes>
61     requires trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>
RequiredEnumTestTraitsbase::trait_helpers::__anonffaff87e0111::RequiredEnumTestTraits62   constexpr RequiredEnumTestTraits(ArgTypes... args)
63       : enum_trait_a(trait_helpers::GetEnum<EnumTraitA>(args...)) {}
64 
65   const EnumTraitA enum_trait_a;
66 };
67 
68 struct OptionalEnumTestTraits {
69   // List of traits that are optional inputs for the constructor below.
70   struct ValidTrait {
71     ValidTrait(EnumTraitA);
72   };
73 
74   // EnumTraitA can optionally be specified.
75   template <class... ArgTypes>
76     requires trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>
OptionalEnumTestTraitsbase::trait_helpers::__anonffaff87e0111::OptionalEnumTestTraits77   constexpr OptionalEnumTestTraits(ArgTypes... args)
78       : enum_trait_a(trait_helpers::GetOptionalEnum<EnumTraitA>(args...)) {}
79 
80   const std::optional<EnumTraitA> enum_trait_a;
81 };
82 
83 }  // namespace
84 
TEST(TraitsBagTest,DefaultConstructor)85 TEST(TraitsBagTest, DefaultConstructor) {
86   constexpr TestTraits trait_test_class;
87 
88   EXPECT_FALSE(trait_test_class.has_example_trait);
89 }
90 
TEST(TraitsBagTest,HasTrait)91 TEST(TraitsBagTest, HasTrait) {
92   constexpr TestTraits with_trait(ExampleTrait{});
93   constexpr TestTraits without_trait;
94 
95   EXPECT_TRUE(with_trait.has_example_trait);
96   EXPECT_FALSE(without_trait.has_example_trait);
97 }
98 
TEST(TraitsBagTest,GetEnumWithDefault)99 TEST(TraitsBagTest, GetEnumWithDefault) {
100   constexpr TestTraits defaults;
101 
102   EXPECT_EQ(defaults.enum_trait_a, EnumTraitA::A);
103   EXPECT_EQ(defaults.enum_trait_b, EnumTraitB::ONE);
104 
105   constexpr TestTraits a(EnumTraitA::A);
106   constexpr TestTraits b(EnumTraitA::B);
107   constexpr TestTraits c(EnumTraitA::C);
108 
109   EXPECT_EQ(a.enum_trait_a, EnumTraitA::A);
110   EXPECT_EQ(a.enum_trait_b, EnumTraitB::ONE);
111 
112   EXPECT_EQ(b.enum_trait_a, EnumTraitA::B);
113   EXPECT_EQ(b.enum_trait_b, EnumTraitB::ONE);
114 
115   EXPECT_EQ(c.enum_trait_a, EnumTraitA::C);
116   EXPECT_EQ(c.enum_trait_b, EnumTraitB::ONE);
117 
118   constexpr TestTraits a_one(EnumTraitA::A, EnumTraitB::ONE);
119   constexpr TestTraits b_one(EnumTraitA::B, EnumTraitB::ONE);
120   constexpr TestTraits c_one(EnumTraitA::C, EnumTraitB::ONE);
121 
122   EXPECT_EQ(a_one.enum_trait_a, EnumTraitA::A);
123   EXPECT_EQ(a_one.enum_trait_b, EnumTraitB::ONE);
124 
125   EXPECT_EQ(b_one.enum_trait_a, EnumTraitA::B);
126   EXPECT_EQ(b_one.enum_trait_b, EnumTraitB::ONE);
127 
128   EXPECT_EQ(c_one.enum_trait_a, EnumTraitA::C);
129   EXPECT_EQ(c_one.enum_trait_b, EnumTraitB::ONE);
130 
131   constexpr TestTraits a_two(EnumTraitA::A, EnumTraitB::TWO);
132   constexpr TestTraits b_two(EnumTraitA::B, EnumTraitB::TWO);
133   constexpr TestTraits c_two(EnumTraitA::C, EnumTraitB::TWO);
134 
135   EXPECT_EQ(a_two.enum_trait_a, EnumTraitA::A);
136   EXPECT_EQ(a_two.enum_trait_b, EnumTraitB::TWO);
137 
138   EXPECT_EQ(b_two.enum_trait_a, EnumTraitA::B);
139   EXPECT_EQ(b_two.enum_trait_b, EnumTraitB::TWO);
140 
141   EXPECT_EQ(c_two.enum_trait_a, EnumTraitA::C);
142   EXPECT_EQ(c_two.enum_trait_b, EnumTraitB::TWO);
143 }
144 
TEST(TraitsBagTest,RequiredEnum)145 TEST(TraitsBagTest, RequiredEnum) {
146   constexpr RequiredEnumTestTraits a(EnumTraitA::A);
147   constexpr RequiredEnumTestTraits b(EnumTraitA::B);
148   constexpr RequiredEnumTestTraits c(EnumTraitA::C);
149 
150   EXPECT_EQ(a.enum_trait_a, EnumTraitA::A);
151   EXPECT_EQ(b.enum_trait_a, EnumTraitA::B);
152   EXPECT_EQ(c.enum_trait_a, EnumTraitA::C);
153 }
154 
TEST(TraitsBagTest,OptionalEnum)155 TEST(TraitsBagTest, OptionalEnum) {
156   constexpr OptionalEnumTestTraits not_set;
157   constexpr OptionalEnumTestTraits set(EnumTraitA::B);
158 
159   EXPECT_FALSE(not_set.enum_trait_a.has_value());
160   ASSERT_TRUE(set.enum_trait_a.has_value());
161   EXPECT_EQ(*set.enum_trait_a, EnumTraitA::B);
162 }
163 
TEST(TraitsBagTest,ValidTraitInheritance)164 TEST(TraitsBagTest, ValidTraitInheritance) {
165   struct ValidTraitsA {
166     ValidTraitsA(EnumTraitA);
167   };
168 
169   struct ValidTraitsB {
170     ValidTraitsB(ValidTraitsA);
171     ValidTraitsB(EnumTraitB);
172   };
173 
174   static_assert(AreValidTraits<ValidTraitsA, EnumTraitA>, "");
175   static_assert(AreValidTraits<ValidTraitsB, EnumTraitA, EnumTraitB>, "");
176 }
177 
TEST(TraitsBagTest,Filtering)178 TEST(TraitsBagTest, Filtering) {
179   using Predicate = Exclude<ExampleTrait, EnumTraitA>;
180   static_assert(std::is_same_v<ExampleTrait2,
181                                decltype(Predicate::Filter(ExampleTrait2{}))>,
182                 "ExampleTrait2 should not be filtered");
183 
184   static_assert(
185       std::is_same_v<EmptyTrait, decltype(Predicate::Filter(ExampleTrait{}))>,
186       "ExampleTrait should be filtered");
187 
188   static_assert(
189       std::is_same_v<EmptyTrait, decltype(Predicate::Filter(EnumTraitA::A))>,
190       "EnumTraitA should be filtered");
191 
192   static_assert(
193       std::is_same_v<EnumTraitB, decltype(Predicate::Filter(EnumTraitB::TWO))>,
194       "EnumTraitB should not be filtered");
195 
196   static_assert(
197       std::is_same_v<EmptyTrait, decltype(Predicate::Filter(EmptyTrait{}))>,
198       "EmptyTrait should not be filtered");
199 }
200 
TEST(TraitsBagTest,FilteredTestTraits)201 TEST(TraitsBagTest, FilteredTestTraits) {
202   FilteredTestTraits filtered(ExampleTrait(), EnumTraitA::C, EnumTraitB::TWO);
203 
204   // ExampleTrait should have been filtered away.
205   EXPECT_FALSE(filtered.has_example_trait);
206 
207   // The other traits should have been set however.
208   EXPECT_EQ(filtered.enum_trait_a, EnumTraitA::C);
209   EXPECT_EQ(filtered.enum_trait_b, EnumTraitB::TWO);
210 }
211 
TEST(TraitsBagTest,EmptyTraitIsValid)212 TEST(TraitsBagTest, EmptyTraitIsValid) {
213   static_assert(IsValidTrait<TestTraits::ValidTrait, EmptyTrait>, "");
214 }
215 
216 }  // namespace trait_helpers
217 }  // namespace base
218