1 // Copyright (c) 2016 Google Inc.
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 <algorithm>
16 #include <utility>
17 #include <vector>
18
19 #include "gmock/gmock.h"
20 #include "source/enum_set.h"
21 #include "test/unit_spirv.h"
22
23 namespace spvtools {
24 namespace {
25
26 using spvtest::ElementsIn;
27 using ::testing::Eq;
28 using ::testing::ValuesIn;
29
TEST(EnumSet,IsEmpty1)30 TEST(EnumSet, IsEmpty1) {
31 EnumSet<uint32_t> set;
32 EXPECT_TRUE(set.IsEmpty());
33 set.Add(0);
34 EXPECT_FALSE(set.IsEmpty());
35 }
36
TEST(EnumSet,IsEmpty2)37 TEST(EnumSet, IsEmpty2) {
38 EnumSet<uint32_t> set;
39 EXPECT_TRUE(set.IsEmpty());
40 set.Add(150);
41 EXPECT_FALSE(set.IsEmpty());
42 }
43
TEST(EnumSet,IsEmpty3)44 TEST(EnumSet, IsEmpty3) {
45 EnumSet<uint32_t> set(4);
46 EXPECT_FALSE(set.IsEmpty());
47 }
48
TEST(EnumSet,IsEmpty4)49 TEST(EnumSet, IsEmpty4) {
50 EnumSet<uint32_t> set(300);
51 EXPECT_FALSE(set.IsEmpty());
52 }
53
TEST(EnumSetHasAnyOf,EmptySetEmptyQuery)54 TEST(EnumSetHasAnyOf, EmptySetEmptyQuery) {
55 const EnumSet<uint32_t> set;
56 const EnumSet<uint32_t> empty;
57 EXPECT_TRUE(set.HasAnyOf(empty));
58 EXPECT_TRUE(EnumSet<uint32_t>().HasAnyOf(EnumSet<uint32_t>()));
59 }
60
TEST(EnumSetHasAnyOf,MaskSetEmptyQuery)61 TEST(EnumSetHasAnyOf, MaskSetEmptyQuery) {
62 EnumSet<uint32_t> set;
63 const EnumSet<uint32_t> empty;
64 set.Add(5);
65 set.Add(8);
66 EXPECT_TRUE(set.HasAnyOf(empty));
67 }
68
TEST(EnumSetHasAnyOf,OverflowSetEmptyQuery)69 TEST(EnumSetHasAnyOf, OverflowSetEmptyQuery) {
70 EnumSet<uint32_t> set;
71 const EnumSet<uint32_t> empty;
72 set.Add(200);
73 set.Add(300);
74 EXPECT_TRUE(set.HasAnyOf(empty));
75 }
76
TEST(EnumSetHasAnyOf,EmptyQuery)77 TEST(EnumSetHasAnyOf, EmptyQuery) {
78 EnumSet<uint32_t> set;
79 const EnumSet<uint32_t> empty;
80 set.Add(5);
81 set.Add(8);
82 set.Add(200);
83 set.Add(300);
84 EXPECT_TRUE(set.HasAnyOf(empty));
85 }
86
TEST(EnumSetHasAnyOf,EmptyQueryAlwaysTrue)87 TEST(EnumSetHasAnyOf, EmptyQueryAlwaysTrue) {
88 EnumSet<uint32_t> set;
89 const EnumSet<uint32_t> empty;
90 EXPECT_TRUE(set.HasAnyOf(empty));
91 set.Add(5);
92 EXPECT_TRUE(set.HasAnyOf(empty));
93
94 EXPECT_TRUE(EnumSet<uint32_t>(100).HasAnyOf(EnumSet<uint32_t>()));
95 }
96
TEST(EnumSetHasAnyOf,ReflexiveMask)97 TEST(EnumSetHasAnyOf, ReflexiveMask) {
98 EnumSet<uint32_t> set(3);
99 set.Add(24);
100 set.Add(30);
101 EXPECT_TRUE(set.HasAnyOf(set));
102 }
103
TEST(EnumSetHasAnyOf,ReflexiveOverflow)104 TEST(EnumSetHasAnyOf, ReflexiveOverflow) {
105 EnumSet<uint32_t> set(200);
106 set.Add(300);
107 set.Add(400);
108 EXPECT_TRUE(set.HasAnyOf(set));
109 }
110
TEST(EnumSetHasAnyOf,Reflexive)111 TEST(EnumSetHasAnyOf, Reflexive) {
112 EnumSet<uint32_t> set(3);
113 set.Add(24);
114 set.Add(300);
115 set.Add(400);
116 EXPECT_TRUE(set.HasAnyOf(set));
117 }
118
TEST(EnumSetHasAnyOf,EmptySetHasNone)119 TEST(EnumSetHasAnyOf, EmptySetHasNone) {
120 EnumSet<uint32_t> set;
121 EnumSet<uint32_t> items;
122 for (uint32_t i = 0; i < 200; ++i) {
123 items.Add(i);
124 EXPECT_FALSE(set.HasAnyOf(items));
125 EXPECT_FALSE(set.HasAnyOf(EnumSet<uint32_t>(i)));
126 }
127 }
128
TEST(EnumSetHasAnyOf,MaskSetMaskQuery)129 TEST(EnumSetHasAnyOf, MaskSetMaskQuery) {
130 EnumSet<uint32_t> set(0);
131 EnumSet<uint32_t> items(1);
132 EXPECT_FALSE(set.HasAnyOf(items));
133 set.Add(2);
134 items.Add(3);
135 EXPECT_FALSE(set.HasAnyOf(items));
136 set.Add(3);
137 EXPECT_TRUE(set.HasAnyOf(items));
138 set.Add(4);
139 EXPECT_TRUE(set.HasAnyOf(items));
140 }
141
TEST(EnumSetHasAnyOf,OverflowSetOverflowQuery)142 TEST(EnumSetHasAnyOf, OverflowSetOverflowQuery) {
143 EnumSet<uint32_t> set(100);
144 EnumSet<uint32_t> items(200);
145 EXPECT_FALSE(set.HasAnyOf(items));
146 set.Add(300);
147 items.Add(400);
148 EXPECT_FALSE(set.HasAnyOf(items));
149 set.Add(200);
150 EXPECT_TRUE(set.HasAnyOf(items));
151 set.Add(500);
152 EXPECT_TRUE(set.HasAnyOf(items));
153 }
154
TEST(EnumSetHasAnyOf,GeneralCase)155 TEST(EnumSetHasAnyOf, GeneralCase) {
156 EnumSet<uint32_t> set(0);
157 EnumSet<uint32_t> items(100);
158 EXPECT_FALSE(set.HasAnyOf(items));
159 set.Add(300);
160 items.Add(4);
161 EXPECT_FALSE(set.HasAnyOf(items));
162 set.Add(5);
163 items.Add(500);
164 EXPECT_FALSE(set.HasAnyOf(items));
165 set.Add(500);
166 EXPECT_TRUE(set.HasAnyOf(items));
167 EXPECT_FALSE(set.HasAnyOf(EnumSet<uint32_t>(20)));
168 EXPECT_FALSE(set.HasAnyOf(EnumSet<uint32_t>(600)));
169 EXPECT_TRUE(set.HasAnyOf(EnumSet<uint32_t>(5)));
170 EXPECT_TRUE(set.HasAnyOf(EnumSet<uint32_t>(300)));
171 EXPECT_TRUE(set.HasAnyOf(EnumSet<uint32_t>(0)));
172 }
173
TEST(EnumSet,DefaultIsEmpty)174 TEST(EnumSet, DefaultIsEmpty) {
175 EnumSet<uint32_t> set;
176 for (uint32_t i = 0; i < 1000; ++i) {
177 EXPECT_FALSE(set.Contains(i));
178 }
179 }
180
TEST(CapabilitySet,ConstructSingleMemberMatrix)181 TEST(CapabilitySet, ConstructSingleMemberMatrix) {
182 CapabilitySet s(SpvCapabilityMatrix);
183 EXPECT_TRUE(s.Contains(SpvCapabilityMatrix));
184 EXPECT_FALSE(s.Contains(SpvCapabilityShader));
185 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(1000)));
186 }
187
TEST(CapabilitySet,ConstructSingleMemberMaxInMask)188 TEST(CapabilitySet, ConstructSingleMemberMaxInMask) {
189 CapabilitySet s(static_cast<SpvCapability>(63));
190 EXPECT_FALSE(s.Contains(SpvCapabilityMatrix));
191 EXPECT_FALSE(s.Contains(SpvCapabilityShader));
192 EXPECT_TRUE(s.Contains(static_cast<SpvCapability>(63)));
193 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(64)));
194 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(1000)));
195 }
196
TEST(CapabilitySet,ConstructSingleMemberMinOverflow)197 TEST(CapabilitySet, ConstructSingleMemberMinOverflow) {
198 // Check the first one that forces overflow beyond the mask.
199 CapabilitySet s(static_cast<SpvCapability>(64));
200 EXPECT_FALSE(s.Contains(SpvCapabilityMatrix));
201 EXPECT_FALSE(s.Contains(SpvCapabilityShader));
202 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(63)));
203 EXPECT_TRUE(s.Contains(static_cast<SpvCapability>(64)));
204 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(1000)));
205 }
206
TEST(CapabilitySet,ConstructSingleMemberMaxOverflow)207 TEST(CapabilitySet, ConstructSingleMemberMaxOverflow) {
208 // Check the max 32-bit signed int.
209 CapabilitySet s(static_cast<SpvCapability>(0x7fffffffu));
210 EXPECT_FALSE(s.Contains(SpvCapabilityMatrix));
211 EXPECT_FALSE(s.Contains(SpvCapabilityShader));
212 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(1000)));
213 EXPECT_TRUE(s.Contains(static_cast<SpvCapability>(0x7fffffffu)));
214 }
215
TEST(CapabilitySet,AddEnum)216 TEST(CapabilitySet, AddEnum) {
217 CapabilitySet s(SpvCapabilityShader);
218 s.Add(SpvCapabilityKernel);
219 s.Add(static_cast<SpvCapability>(42));
220 EXPECT_FALSE(s.Contains(SpvCapabilityMatrix));
221 EXPECT_TRUE(s.Contains(SpvCapabilityShader));
222 EXPECT_TRUE(s.Contains(SpvCapabilityKernel));
223 EXPECT_TRUE(s.Contains(static_cast<SpvCapability>(42)));
224 }
225
TEST(CapabilitySet,InitializerListEmpty)226 TEST(CapabilitySet, InitializerListEmpty) {
227 CapabilitySet s{};
228 for (uint32_t i = 0; i < 1000; i++) {
229 EXPECT_FALSE(s.Contains(static_cast<SpvCapability>(i)));
230 }
231 }
232
233 struct ForEachCase {
234 CapabilitySet capabilities;
235 std::vector<SpvCapability> expected;
236 };
237
238 using CapabilitySetForEachTest = ::testing::TestWithParam<ForEachCase>;
239
TEST_P(CapabilitySetForEachTest,CallsAsExpected)240 TEST_P(CapabilitySetForEachTest, CallsAsExpected) {
241 EXPECT_THAT(ElementsIn(GetParam().capabilities), Eq(GetParam().expected));
242 }
243
TEST_P(CapabilitySetForEachTest,CopyConstructor)244 TEST_P(CapabilitySetForEachTest, CopyConstructor) {
245 CapabilitySet copy(GetParam().capabilities);
246 EXPECT_THAT(ElementsIn(copy), Eq(GetParam().expected));
247 }
248
TEST_P(CapabilitySetForEachTest,MoveConstructor)249 TEST_P(CapabilitySetForEachTest, MoveConstructor) {
250 // We need a writable copy to move from.
251 CapabilitySet copy(GetParam().capabilities);
252 CapabilitySet moved(std::move(copy));
253 EXPECT_THAT(ElementsIn(moved), Eq(GetParam().expected));
254
255 // The moved-from set is empty.
256 EXPECT_THAT(ElementsIn(copy), Eq(std::vector<SpvCapability>{}));
257 }
258
TEST_P(CapabilitySetForEachTest,OperatorEquals)259 TEST_P(CapabilitySetForEachTest, OperatorEquals) {
260 CapabilitySet assigned = GetParam().capabilities;
261 EXPECT_THAT(ElementsIn(assigned), Eq(GetParam().expected));
262 }
263
TEST_P(CapabilitySetForEachTest,OperatorEqualsSelfAssign)264 TEST_P(CapabilitySetForEachTest, OperatorEqualsSelfAssign) {
265 CapabilitySet assigned{GetParam().capabilities};
266 assigned = assigned;
267 EXPECT_THAT(ElementsIn(assigned), Eq(GetParam().expected));
268 }
269
270 INSTANTIATE_TEST_SUITE_P(Samples, CapabilitySetForEachTest,
271 ValuesIn(std::vector<ForEachCase>{
272 {{}, {}},
273 {{SpvCapabilityMatrix}, {SpvCapabilityMatrix}},
274 {{SpvCapabilityKernel, SpvCapabilityShader},
275 {SpvCapabilityShader, SpvCapabilityKernel}},
276 {{static_cast<SpvCapability>(999)},
277 {static_cast<SpvCapability>(999)}},
278 {{static_cast<SpvCapability>(0x7fffffff)},
279 {static_cast<SpvCapability>(0x7fffffff)}},
280 // Mixture and out of order
281 {{static_cast<SpvCapability>(0x7fffffff),
282 static_cast<SpvCapability>(100),
283 SpvCapabilityShader, SpvCapabilityMatrix},
284 {SpvCapabilityMatrix, SpvCapabilityShader,
285 static_cast<SpvCapability>(100),
286 static_cast<SpvCapability>(0x7fffffff)}},
287 }));
288
289 } // namespace
290 } // namespace spvtools
291