blob: eea052ba33e8eb8e25c833da5daa87e0ab032390 [file] [log] [blame]
Michael Wright44753b12020-07-08 13:48:11 +01001/*
2 * Copyright 2020 The Android Open Source Project
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
Dominik Laskowski2f01d772022-03-23 16:01:29 -070017#include <ftl/flags.h>
Michael Wright44753b12020-07-08 13:48:11 +010018#include <gtest/gtest.h>
Michael Wright44753b12020-07-08 13:48:11 +010019
20#include <type_traits>
21
22namespace android::test {
23
Dominik Laskowski2f01d772022-03-23 16:01:29 -070024using ftl::Flags;
25using namespace ftl::flag_operators;
Michael Wright44753b12020-07-08 13:48:11 +010026
Dominik Laskowski75788452021-02-09 18:51:25 -080027enum class TestFlags : uint8_t { ONE = 0x1, TWO = 0x2, THREE = 0x4 };
Michael Wright44753b12020-07-08 13:48:11 +010028
Michael Wright44753b12020-07-08 13:48:11 +010029TEST(Flags, Test) {
30 Flags<TestFlags> flags = TestFlags::ONE;
31 ASSERT_TRUE(flags.test(TestFlags::ONE));
32 ASSERT_FALSE(flags.test(TestFlags::TWO));
33 ASSERT_FALSE(flags.test(TestFlags::THREE));
34}
35
36TEST(Flags, Any) {
37 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
38 ASSERT_TRUE(flags.any(TestFlags::ONE));
39 ASSERT_TRUE(flags.any(TestFlags::TWO));
40 ASSERT_FALSE(flags.any(TestFlags::THREE));
41 ASSERT_TRUE(flags.any(TestFlags::ONE | TestFlags::TWO));
42 ASSERT_TRUE(flags.any(TestFlags::TWO | TestFlags::THREE));
43 ASSERT_TRUE(flags.any(TestFlags::ONE | TestFlags::THREE));
44 ASSERT_TRUE(flags.any(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE));
45}
46
47TEST(Flags, All) {
48 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
49 ASSERT_TRUE(flags.all(TestFlags::ONE));
50 ASSERT_TRUE(flags.all(TestFlags::TWO));
51 ASSERT_FALSE(flags.all(TestFlags::THREE));
52 ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::TWO));
53 ASSERT_FALSE(flags.all(TestFlags::TWO | TestFlags::THREE));
54 ASSERT_FALSE(flags.all(TestFlags::ONE | TestFlags::THREE));
55 ASSERT_FALSE(flags.all(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE));
56}
57
58TEST(Flags, DefaultConstructor_hasNoFlagsSet) {
59 Flags<TestFlags> flags;
60 ASSERT_FALSE(flags.any(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE));
61}
62
63TEST(Flags, NotOperator_onEmptyFlagsSetsAllFlags) {
64 Flags<TestFlags> flags;
65 flags = ~flags;
66 ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE));
67}
68
69TEST(Flags, NotOperator_onNonEmptyFlagsInvertsFlags) {
70 Flags<TestFlags> flags = TestFlags::TWO;
71 flags = ~flags;
72 ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::THREE));
73 ASSERT_FALSE(flags.test(TestFlags::TWO));
74}
75
76TEST(Flags, OrOperator_withNewFlag) {
77 Flags<TestFlags> flags = TestFlags::ONE;
78 Flags<TestFlags> flags2 = flags | TestFlags::TWO;
79 ASSERT_FALSE(flags2.test(TestFlags::THREE));
80 ASSERT_TRUE(flags2.all(TestFlags::ONE | TestFlags::TWO));
81}
82
83TEST(Flags, OrOperator_withExistingFlag) {
84 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE;
85 Flags<TestFlags> flags2 = flags | TestFlags::THREE;
86 ASSERT_FALSE(flags2.test(TestFlags::TWO));
87 ASSERT_TRUE(flags2.all(TestFlags::ONE | TestFlags::THREE));
88}
89
90TEST(Flags, OrEqualsOperator_withNewFlag) {
91 Flags<TestFlags> flags;
92 flags |= TestFlags::THREE;
93 ASSERT_TRUE(flags.test(TestFlags::THREE));
94 ASSERT_FALSE(flags.any(TestFlags::ONE | TestFlags::TWO));
95}
96
97TEST(Flags, OrEqualsOperator_withExistingFlag) {
98 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE;
99 flags |= TestFlags::THREE;
100 ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::THREE));
101 ASSERT_FALSE(flags.test(TestFlags::TWO));
102}
103
104TEST(Flags, AndOperator_withOneSetFlag) {
105 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE;
106 Flags<TestFlags> andFlags = flags & TestFlags::THREE;
107 ASSERT_TRUE(andFlags.test(TestFlags::THREE));
108 ASSERT_FALSE(andFlags.any(TestFlags::ONE | TestFlags::TWO));
109}
110
111TEST(Flags, AndOperator_withMultipleSetFlags) {
112 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE;
113 Flags<TestFlags> andFlags = flags & (TestFlags::ONE | TestFlags::THREE);
114 ASSERT_TRUE(andFlags.all(TestFlags::ONE | TestFlags::THREE));
115 ASSERT_FALSE(andFlags.test(TestFlags::TWO));
116}
117
118TEST(Flags, AndOperator_withNoSetFlags) {
119 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE;
120 Flags<TestFlags> andFlags = flags & TestFlags::TWO;
121 ASSERT_FALSE(andFlags.any(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE));
122}
123
124TEST(Flags, Equality) {
125 Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO;
126 Flags<TestFlags> flags2 = TestFlags::ONE | TestFlags::TWO;
127 ASSERT_EQ(flags1, flags2);
128}
129
130TEST(Flags, Inequality) {
131 Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO;
132 Flags<TestFlags> flags2 = TestFlags::ONE | TestFlags::THREE;
133 ASSERT_NE(flags1, flags2);
134}
135
136TEST(Flags, EqualsOperator) {
137 Flags<TestFlags> flags;
138 flags = TestFlags::ONE;
139 ASSERT_TRUE(flags.test(TestFlags::ONE));
140 ASSERT_FALSE(flags.any(TestFlags::TWO | TestFlags::THREE));
141}
142
143TEST(Flags, EqualsOperator_DontShareState) {
144 Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO;
145 Flags<TestFlags> flags2 = flags1;
146 ASSERT_EQ(flags1, flags2);
147
148 flags1 &= TestFlags::TWO;
149 ASSERT_NE(flags1, flags2);
150}
151
Chris Yed3fef462021-03-07 17:10:08 -0800152TEST(Flags, GetValue) {
153 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
154 ASSERT_EQ(flags.get(), 0x3);
155}
156
Michael Wright8759d672020-07-21 00:46:45 +0100157TEST(Flags, String_NoFlags) {
Michael Wright44753b12020-07-08 13:48:11 +0100158 Flags<TestFlags> flags;
159 ASSERT_EQ(flags.string(), "0x0");
160}
161
Michael Wright8759d672020-07-21 00:46:45 +0100162TEST(Flags, String_KnownValues) {
Michael Wright44753b12020-07-08 13:48:11 +0100163 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
Michael Wright8759d672020-07-21 00:46:45 +0100164 ASSERT_EQ(flags.string(), "ONE | TWO");
Michael Wright44753b12020-07-08 13:48:11 +0100165}
166
Michael Wright8759d672020-07-21 00:46:45 +0100167TEST(Flags, String_UnknownValues) {
168 auto flags = Flags<TestFlags>(0b1011);
Dominik Laskowski75788452021-02-09 18:51:25 -0800169 ASSERT_EQ(flags.string(), "ONE | TWO | 0b1000");
Michael Wright44753b12020-07-08 13:48:11 +0100170}
171
Michael Wright75d9e662020-07-11 23:54:40 +0100172TEST(FlagsIterator, IteratesOverAllFlags) {
173 Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO;
174 Flags<TestFlags> flags2;
175 for (TestFlags f : flags1) {
176 flags2 |= f;
177 }
178 ASSERT_EQ(flags2, flags1);
179}
180
181TEST(FlagsIterator, IteratesInExpectedOrder) {
182 const std::vector<TestFlags> flagOrder = {TestFlags::ONE, TestFlags::TWO};
183 Flags<TestFlags> flags;
184 for (TestFlags f : flagOrder) {
185 flags |= f;
186 }
187
188 size_t idx = 0;
189 auto iter = flags.begin();
190 while (iter != flags.end() && idx < flagOrder.size()) {
191 // Make sure the order is what we expect
192 ASSERT_EQ(*iter, flagOrder[idx]);
193 iter++;
194 idx++;
195 }
196 ASSERT_EQ(iter, flags.end());
197}
198TEST(FlagsIterator, PostFixIncrement) {
199 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
200 auto iter = flags.begin();
201 ASSERT_EQ(*(iter++), TestFlags::ONE);
202 ASSERT_EQ(*iter, TestFlags::TWO);
203 ASSERT_EQ(*(iter++), TestFlags::TWO);
204 ASSERT_EQ(iter, flags.end());
205}
206
207TEST(FlagsIterator, PreFixIncrement) {
208 Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
209 auto iter = flags.begin();
210 ASSERT_EQ(*++iter, TestFlags::TWO);
211 ASSERT_EQ(++iter, flags.end());
212}
213
Dominik Laskowski75788452021-02-09 18:51:25 -0800214} // namespace android::test