• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/utils/enum_set.h"
16 
17 #include <sstream>
18 #include <vector>
19 
20 #include "gmock/gmock.h"
21 
22 namespace tint {
23 namespace utils {
24 namespace {
25 
26 using ::testing::ElementsAre;
27 
28 enum class E { A = 0, B = 3, C = 7 };
29 
operator <<(std::ostream & out,E e)30 std::ostream& operator<<(std::ostream& out, E e) {
31   switch (e) {
32     case E::A:
33       return out << "A";
34     case E::B:
35       return out << "B";
36     case E::C:
37       return out << "C";
38   }
39   return out << "E(" << static_cast<uint32_t>(e) << ")";
40 }
41 
TEST(EnumSetTest,ConstructEmpty)42 TEST(EnumSetTest, ConstructEmpty) {
43   EnumSet<E> set;
44   EXPECT_FALSE(set.Contains(E::A));
45   EXPECT_FALSE(set.Contains(E::B));
46   EXPECT_FALSE(set.Contains(E::C));
47   EXPECT_TRUE(set.Empty());
48 }
49 
TEST(EnumSetTest,ConstructWithSingle)50 TEST(EnumSetTest, ConstructWithSingle) {
51   EnumSet<E> set(E::B);
52   EXPECT_FALSE(set.Contains(E::A));
53   EXPECT_TRUE(set.Contains(E::B));
54   EXPECT_FALSE(set.Contains(E::C));
55   EXPECT_FALSE(set.Empty());
56 }
57 
TEST(EnumSetTest,ConstructWithMultiple)58 TEST(EnumSetTest, ConstructWithMultiple) {
59   EnumSet<E> set(E::A, E::C);
60   EXPECT_TRUE(set.Contains(E::A));
61   EXPECT_FALSE(set.Contains(E::B));
62   EXPECT_TRUE(set.Contains(E::C));
63   EXPECT_FALSE(set.Empty());
64 }
65 
TEST(EnumSetTest,AssignSet)66 TEST(EnumSetTest, AssignSet) {
67   EnumSet<E> set;
68   set = EnumSet<E>(E::A, E::C);
69   EXPECT_TRUE(set.Contains(E::A));
70   EXPECT_FALSE(set.Contains(E::B));
71   EXPECT_TRUE(set.Contains(E::C));
72 }
73 
TEST(EnumSetTest,AssignEnum)74 TEST(EnumSetTest, AssignEnum) {
75   EnumSet<E> set(E::A);
76   set = E::B;
77   EXPECT_FALSE(set.Contains(E::A));
78   EXPECT_TRUE(set.Contains(E::B));
79   EXPECT_FALSE(set.Contains(E::C));
80 }
81 
TEST(EnumSetTest,AddEnum)82 TEST(EnumSetTest, AddEnum) {
83   EnumSet<E> set;
84   set.Add(E::B);
85   EXPECT_FALSE(set.Contains(E::A));
86   EXPECT_TRUE(set.Contains(E::B));
87   EXPECT_FALSE(set.Contains(E::C));
88 }
89 
TEST(EnumSetTest,RemoveEnum)90 TEST(EnumSetTest, RemoveEnum) {
91   EnumSet<E> set(E::A, E::B);
92   set.Remove(E::B);
93   EXPECT_TRUE(set.Contains(E::A));
94   EXPECT_FALSE(set.Contains(E::B));
95   EXPECT_FALSE(set.Contains(E::C));
96 }
97 
TEST(EnumSetTest,AddEnums)98 TEST(EnumSetTest, AddEnums) {
99   EnumSet<E> set;
100   set.Add(E::B, E::C);
101   EXPECT_FALSE(set.Contains(E::A));
102   EXPECT_TRUE(set.Contains(E::B));
103   EXPECT_TRUE(set.Contains(E::C));
104 }
105 
TEST(EnumSetTest,RemoveEnums)106 TEST(EnumSetTest, RemoveEnums) {
107   EnumSet<E> set(E::A, E::B);
108   set.Remove(E::C, E::B);
109   EXPECT_TRUE(set.Contains(E::A));
110   EXPECT_FALSE(set.Contains(E::B));
111   EXPECT_FALSE(set.Contains(E::C));
112 }
113 
TEST(EnumSetTest,AddEnumSet)114 TEST(EnumSetTest, AddEnumSet) {
115   EnumSet<E> set;
116   set.Add(EnumSet<E>{E::B, E::C});
117   EXPECT_FALSE(set.Contains(E::A));
118   EXPECT_TRUE(set.Contains(E::B));
119   EXPECT_TRUE(set.Contains(E::C));
120 }
121 
TEST(EnumSetTest,RemoveEnumSet)122 TEST(EnumSetTest, RemoveEnumSet) {
123   EnumSet<E> set(E::A, E::B);
124   set.Remove(EnumSet<E>{E::B, E::C});
125   EXPECT_TRUE(set.Contains(E::A));
126   EXPECT_FALSE(set.Contains(E::B));
127   EXPECT_FALSE(set.Contains(E::C));
128 }
129 
TEST(EnumSetTest,OperatorPlusEnum)130 TEST(EnumSetTest, OperatorPlusEnum) {
131   EnumSet<E> set = EnumSet<E>{E::B} + E::C;
132   EXPECT_FALSE(set.Contains(E::A));
133   EXPECT_TRUE(set.Contains(E::B));
134   EXPECT_TRUE(set.Contains(E::C));
135 }
136 
TEST(EnumSetTest,OperatorMinusEnum)137 TEST(EnumSetTest, OperatorMinusEnum) {
138   EnumSet<E> set = EnumSet<E>{E::A, E::B} - E::B;
139   EXPECT_TRUE(set.Contains(E::A));
140   EXPECT_FALSE(set.Contains(E::B));
141   EXPECT_FALSE(set.Contains(E::C));
142 }
143 
TEST(EnumSetTest,OperatorPlusSet)144 TEST(EnumSetTest, OperatorPlusSet) {
145   EnumSet<E> set = EnumSet<E>{E::B} + EnumSet<E>{E::B, E::C};
146   EXPECT_FALSE(set.Contains(E::A));
147   EXPECT_TRUE(set.Contains(E::B));
148   EXPECT_TRUE(set.Contains(E::C));
149 }
150 
TEST(EnumSetTest,OperatorMinusSet)151 TEST(EnumSetTest, OperatorMinusSet) {
152   EnumSet<E> set = EnumSet<E>{E::A, E::B} - EnumSet<E>{E::B, E::C};
153   EXPECT_TRUE(set.Contains(E::A));
154   EXPECT_FALSE(set.Contains(E::B));
155   EXPECT_FALSE(set.Contains(E::C));
156 }
157 
TEST(EnumSetTest,OperatorAnd)158 TEST(EnumSetTest, OperatorAnd) {
159   EnumSet<E> set = EnumSet<E>{E::A, E::B} & EnumSet<E>{E::B, E::C};
160   EXPECT_FALSE(set.Contains(E::A));
161   EXPECT_TRUE(set.Contains(E::B));
162   EXPECT_FALSE(set.Contains(E::C));
163 }
164 
TEST(EnumSetTest,EqualitySet)165 TEST(EnumSetTest, EqualitySet) {
166   EXPECT_TRUE(EnumSet<E>(E::A, E::B) == EnumSet<E>(E::A, E::B));
167   EXPECT_FALSE(EnumSet<E>(E::A, E::B) == EnumSet<E>(E::A, E::C));
168 }
169 
TEST(EnumSetTest,InequalitySet)170 TEST(EnumSetTest, InequalitySet) {
171   EXPECT_FALSE(EnumSet<E>(E::A, E::B) != EnumSet<E>(E::A, E::B));
172   EXPECT_TRUE(EnumSet<E>(E::A, E::B) != EnumSet<E>(E::A, E::C));
173 }
174 
TEST(EnumSetTest,EqualityEnum)175 TEST(EnumSetTest, EqualityEnum) {
176   EXPECT_TRUE(EnumSet<E>(E::A) == E::A);
177   EXPECT_FALSE(EnumSet<E>(E::B) == E::A);
178   EXPECT_FALSE(EnumSet<E>(E::B) == E::C);
179   EXPECT_FALSE(EnumSet<E>(E::A, E::B) == E::A);
180   EXPECT_FALSE(EnumSet<E>(E::A, E::B) == E::B);
181   EXPECT_FALSE(EnumSet<E>(E::A, E::B) == E::C);
182 }
183 
TEST(EnumSetTest,InequalityEnum)184 TEST(EnumSetTest, InequalityEnum) {
185   EXPECT_FALSE(EnumSet<E>(E::A) != E::A);
186   EXPECT_TRUE(EnumSet<E>(E::B) != E::A);
187   EXPECT_TRUE(EnumSet<E>(E::B) != E::C);
188   EXPECT_TRUE(EnumSet<E>(E::A, E::B) != E::A);
189   EXPECT_TRUE(EnumSet<E>(E::A, E::B) != E::B);
190   EXPECT_TRUE(EnumSet<E>(E::A, E::B) != E::C);
191 }
192 
TEST(EnumSetTest,Hash)193 TEST(EnumSetTest, Hash) {
194   auto hash = [&](EnumSet<E> s) { return std::hash<EnumSet<E>>()(s); };
195   EXPECT_EQ(hash(EnumSet<E>(E::A, E::B)), hash(EnumSet<E>(E::A, E::B)));
196   EXPECT_NE(hash(EnumSet<E>(E::A, E::B)), hash(EnumSet<E>(E::A, E::C)));
197 }
198 
TEST(EnumSetTest,Value)199 TEST(EnumSetTest, Value) {
200   EXPECT_EQ(EnumSet<E>().Value(), 0u);
201   EXPECT_EQ(EnumSet<E>(E::A).Value(), 1u);
202   EXPECT_EQ(EnumSet<E>(E::B).Value(), 8u);
203   EXPECT_EQ(EnumSet<E>(E::C).Value(), 128u);
204   EXPECT_EQ(EnumSet<E>(E::A, E::C).Value(), 129u);
205 }
206 
TEST(EnumSetTest,Iterator)207 TEST(EnumSetTest, Iterator) {
208   auto set = EnumSet<E>(E::C, E::A);
209 
210   auto it = set.begin();
211   EXPECT_EQ(*it, E::A);
212   EXPECT_NE(it, set.end());
213   ++it;
214   EXPECT_EQ(*it, E::C);
215   EXPECT_NE(it, set.end());
216   ++it;
217   EXPECT_EQ(it, set.end());
218 }
219 
TEST(EnumSetTest,IteratorEmpty)220 TEST(EnumSetTest, IteratorEmpty) {
221   auto set = EnumSet<E>();
222   EXPECT_EQ(set.begin(), set.end());
223 }
224 
TEST(EnumSetTest,Loop)225 TEST(EnumSetTest, Loop) {
226   auto set = EnumSet<E>(E::C, E::A);
227 
228   std::vector<E> seen;
229   for (auto e : set) {
230     seen.emplace_back(e);
231   }
232 
233   EXPECT_THAT(seen, ElementsAre(E::A, E::C));
234 }
235 
TEST(EnumSetTest,Ostream)236 TEST(EnumSetTest, Ostream) {
237   std::stringstream ss;
238   ss << EnumSet<E>(E::A, E::C);
239   EXPECT_EQ(ss.str(), "{A, C}");
240 }
241 
242 }  // namespace
243 }  // namespace utils
244 }  // namespace tint
245