1/*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
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
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
18
19#include <meta/api/util.h>
20#include <meta/base/bit_field.h>
21#include <meta/ext/object.h>
22#include <meta/interface/intf_object.h>
23#include <meta/interface/intf_object_registry.h>
24
25#include "src/test_runner.h"
26
27namespace {
28    const int TESTVALUE = 16;
29}
30
31enum TestFlagBits : uint32_t {
32    FLAG1 = 1,
33    FLAG2 = 2,
34    FLAG4 = 4,
35};
36
37using TestFlags = META_NS::EnumBitField<TestFlagBits, uint64_t>;
38META_TYPE(TestFlags)
39
40META_BEGIN_NAMESPACE()
41
42using namespace testing::ext;
43
44META_REGISTER_INTERFACE(ITestFlagsInterface, "eba09b49-6efe-4b97-b809-981569a935e7")
45
46class ITestFlagsInterface : public CORE_NS::IInterface {
47    META_INTERFACE2(CORE_NS::IInterface, ITestFlagsInterface)
48public:
49    META_PROPERTY(TestFlags, Flags);
50};
51
52META_REGISTER_CLASS(
53    BitfieldPropertyObject, "e62b0ab3-b07d-4423-b2bc-d4a522db8ded", META_NS::ObjectCategoryBits::NO_CATEGORY)
54
55class BitfieldPropertyObject final
56    : public META_NS::MetaObjectFwd<BitfieldPropertyObject, ClassId::BitfieldPropertyObject,
57        META_NS::ClassId::MetaObject, ITestFlagsInterface> {
58    META_IMPLEMENT_PROPERTY(TestFlags, Flags, TestFlagBits::FLAG2)
59};
60
61
62class BitfieldPropertyTest : public testing::Test {
63public:
64    static void SetUpTestSuite()
65    {
66        SetTest();
67        RegisterObjectType<BitfieldPropertyObject>();
68    }
69    static void TearDownTestSuite()
70    {
71        UnregisterObjectType<BitfieldPropertyObject>();
72        ResetTest();
73    }
74    void SetUp() override
75    {
76        object_ = Meta::GetObjectRegistry().Create<ITestFlagsInterface> (ClassId::BitfieldPropertyObject);
77    }
78    void TearDown() override
79    {
80        object_.reset();
81    }
82protected:
83    ITestFlagsInterface::Ptr object_;
84};
85
86MATCHER_P (ExactBitsSet, n, "")
87{
88    return arg == n;
89}
90
91/**
92 * @tc.name: BitfieldPropertyTest
93 * @tc.desc: test GetValue function
94 * @tc.type: FUNC
95 * @tc.require: I7DMS1
96 */
97HWTEST_F(BitfieldPropertyTest, GetValue, TestSize.Level1)
98{
99    EXPECT_EQ(GetValue(object_->Flags()), TestFlagBits::FLAG2);
100}
101
102/**
103 * @tc.name: BitfieldPropertyTest
104 * @tc.desc: test SetValue function
105 * @tc.type: FUNC
106 * @tc.require: I7DMS1
107 */
108HWTEST_F(BitfieldPropertyTest, SetValue, TestSize.Level1)
109{
110    SetValue(object_->Flags(), TestFlagBits::FLAG1 | TestFlagBits::FLAG4);
111    EXPECT_EQ(GetValue(object_->Flags()), TestFlagBits::FLAG1 | TestFlagBits::FLAG4);
112}
113
114/**
115 * @tc.name: BitfieldPropertyTest
116 * @tc.desc: test SetValue function
117 * @tc.type: FUNC
118 * @tc.require: I7DMS1
119 */
120HWTEST_F(BitfieldPropertyTest, SetValueOp, TestSize.Level1)
121{
122    TestFlags value1 = TestFlagBits::FLAG2;
123    SetValue(object_->Flags(), value1 | TestFlagBits::FLAG1 | TestFlagBits::FLAG4);
124    EXPECT_EQ(GetValue(object_->Flags()), TestFlagBits::FLAG1 | TestFlagBits::FLAG2 | TestFlagBits::FLAG4);
125}
126
127/**
128 * @tc.name: BitfieldPropertyTest
129 * @tc.desc: test Or function
130 * @tc.type: FUNC
131 * @tc.require: I7DMS1
132 */
133HWTEST_F(BitfieldPropertyTest, Or, TestSize.Level1)
134{
135    EnumBitField<TestFlagBits> value1(TestFlagBits::FLAG1);
136    EnumBitField<TestFlagBits> value2(TestFlagBits::FLAG2 | TestFlagBits::FLAG4);
137    EXPECT_THAT(
138        (value1 | value2).GetValue(), ExactBitsSet(TestFlagBits::FLAG1 | TestFlagBits::FLAG2 | TestFlagBits::FLAG4));
139}
140
141/**
142 * @tc.name: BitfieldPropertyTest
143 * @tc.desc: test And function
144 * @tc.type: FUNC
145 * @tc.require: I7DMS1
146 */
147HWTEST_F(BitfieldPropertyTest, And, TestSize.Level1)
148{
149    EnumBitField<TestFlagBits> value1(TestFlagBits::FLAG1);
150    EnumBitField<TestFlagBits> value2(TestFlagBits::FLAG1 | TestFlagBits::FLAG2 | TestFlagBits::FLAG4);
151    EXPECT_THAT((value1 & value2).GetValue(), ExactBitsSet(TestFlagBits::FLAG1));
152}
153
154/**
155 * @tc.name: BitfieldPropertyTest
156 * @tc.desc: test Xor function
157 * @tc.type: FUNC
158 * @tc.require: I7DMS1
159 */
160HWTEST_F(BitfieldPropertyTest, Xor, TestSize.Level1)
161{
162    EnumBitField<TestFlagBits> value1(TestFlagBits::FLAG1);
163    EnumBitField<TestFlagBits> value2(TestFlagBits::FLAG1 | TestFlagBits::FLAG2 | TestFlagBits::FLAG4);
164    EXPECT_THAT((value1 ^ value2).GetValue(), ExactBitsSet(TestFlagBits::FLAG2 | TestFlagBits::FLAG4));
165}
166
167/**
168 * @tc.name: BitfieldPropertyTest
169 * @tc.desc: test Not function
170 * @tc.type: FUNC
171 * @tc.require: I7DMS1
172 */
173HWTEST_F(BitfieldPropertyTest, Not, TestSize.Level1)
174{
175    EnumBitField<TestFlagBits> value1(TestFlagBits::FLAG1);
176    EXPECT_THAT((~value1).GetValue(), ExactBitsSet(~TestFlagBits::FLAG1));
177}
178
179/**
180 * @tc.name: BitfieldPropertyTest
181 * @tc.desc: test SetAndClear function
182 * @tc.type: FUNC
183 * @tc.require: I7DMS1
184 */
185HWTEST_F(BitfieldPropertyTest, SetAndClear, TestSize.Level1)
186{
187    EnumBitField<TestFlagBits> value(TestFlagBits::FLAG1);
188    EXPECT_TRUE(value.IsSet(TestFlagBits::FLAG1));
189    EXPECT_FALSE(value.IsSet(TestFlagBits::FLAG2));
190
191    value.Set(TestFlagBits::FLAG2);
192    EXPECT_TRUE(value.IsSet(TestFlagBits::FLAG2));
193
194    value.Clear(TestFlagBits::FLAG1);
195    EXPECT_FALSE(value.IsSet(TestFlagBits::FLAG1));
196    EXPECT_TRUE(value.IsSet(TestFlagBits::FLAG2));
197}
198
199enum ExtTestFlagBits : uint32_t {
200    FLAG1 = 1,
201    FLAG2 = 2,
202    FLAG4 = 4,
203};
204
205using ExtTestFlags = META_NS::SubEnumBitField<ExtTestFlagBits, TestFlags, TESTVALUE, TESTVALUE>;
206
207/**
208 * @tc.name: BitfieldPropertyTest
209 * @tc.desc: test Value function
210 * @tc.type: FUNC
211 * @tc.require: I7DMS1
212 */
213HWTEST_F(BitfieldPropertyTest, Value, TestSize.Level1)
214{
215    TestFlags base(TestFlagBits::FLAG1);
216    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
217
218    TestFlags res = base | ext;
219    EXPECT_THAT(res.GetValue(), ExactBitsSet(TestFlagBits::FLAG1 | (ExtTestFlagBits::FLAG2 << 16)));
220
221    ExtTestFlags sub(res);
222    EXPECT_EQ(ext, sub);
223    EXPECT_THAT(sub.GetValue(), ExactBitsSet(ExtTestFlagBits::FLAG2 << 16));
224    EXPECT_THAT((ExtTestFlagBits)sub, ExactBitsSet(ExtTestFlagBits::FLAG2));
225}
226
227/**
228 * @tc.name: BitfieldPropertyTest
229 * @tc.desc: test Or1 function
230 * @tc.type: FUNC
231 * @tc.require: I7DMS1
232 */
233HWTEST_F(BitfieldPropertyTest, Or1, TestSize.Level1)
234{
235    TestFlags base(TestFlagBits::FLAG1);
236    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
237
238    EXPECT_THAT(base | ext, ExactBitsSet(TestFlagBits::FLAG1 | (ExtTestFlagBits::FLAG2 << 16)));
239}
240
241/**
242 * @tc.name: BitfieldPropertyTest
243 * @tc.desc: test And1 function
244 * @tc.type: FUNC
245 * @tc.require: I7DMS1
246 */
247HWTEST_F(BitfieldPropertyTest, And1, TestSize.Level1)
248{
249    TestFlags base(TestFlagBits::FLAG1);
250    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
251    TestFlags res = base | ext;
252    EXPECT_THAT(res & ext, ExactBitsSet(ExtTestFlagBits::FLAG2 << 16));
253    EXPECT_THAT(res & base, ExactBitsSet(TestFlagBits::FLAG1));
254}
255
256/**
257 * @tc.name: BitfieldPropertyTest
258 * @tc.desc: test Xor1 function
259 * @tc.type: FUNC
260 * @tc.require: I7DMS1
261 */
262HWTEST_F(BitfieldPropertyTest, Xor1, TestSize.Level1)
263{
264    TestFlags base(TestFlagBits::FLAG1);
265    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
266    TestFlags res = base | ext;
267    EXPECT_THAT(res ^ ext, ExactBitsSet(TestFlagBits::FLAG1));
268    EXPECT_THAT(res ^ base, ExactBitsSet(ExtTestFlagBits::FLAG2 << 16));
269}
270
271/**
272 * @tc.name: BitfieldPropertyTest
273 * @tc.desc: test Not1 function
274 * @tc.type: FUNC
275 * @tc.require: I7DMS1
276 */
277HWTEST_F(BitfieldPropertyTest, Not1, TestSize.Level1)
278{
279    TestFlags base(TestFlagBits::FLAG1);
280    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
281    TestFlags res = base | ext;
282    EXPECT_THAT(res & ~ext, ExactBitsSet(TestFlagBits::FLAG1));
283    EXPECT_THAT(res & ~base, ExactBitsSet(ExtTestFlagBits::FLAG2 << 16));
284}
285
286/**
287 * @tc.name: BitfieldPropertyTest
288 * @tc.desc: test SetAndClear1 function
289 * @tc.type: FUNC
290 * @tc.require: I7DMS1
291 */
292HWTEST_F(BitfieldPropertyTest, SetAndClear1, TestSize.Level1)
293{
294    TestFlags base(TestFlagBits::FLAG1);
295    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
296
297    EXPECT_FALSE(ext.IsSet(ExtTestFlagBits::FLAG1));
298    EXPECT_TRUE(ext.IsSet(ExtTestFlagBits::FLAG2));
299    ext.Set(ExtTestFlagBits::FLAG1);
300    EXPECT_TRUE(ext.IsSet(ExtTestFlagBits::FLAG1));
301    ext.Clear(ExtTestFlagBits::FLAG2);
302    EXPECT_FALSE(ext.IsSet(ExtTestFlagBits::FLAG2));
303    EXPECT_TRUE(ext.IsSet(ExtTestFlagBits::FLAG1));
304
305    TestFlags value = base | ext;
306    EXPECT_TRUE(value.IsSet(TestFlagBits::FLAG1));
307    EXPECT_FALSE(value.IsSet(TestFlagBits::FLAG2));
308    value.Clear(TestFlagBits::FLAG1);
309    ExtTestFlags ext2 = value;
310    EXPECT_FALSE(ext2.IsSet(ExtTestFlagBits::FLAG2));
311    EXPECT_TRUE(ext2.IsSet(ExtTestFlagBits::FLAG1));
312}
313
314/**
315 * @tc.name: BitfieldPropertyTest
316 * @tc.desc: test SetAndClear1 function
317 * @tc.type: FUNC
318 * @tc.require: I7DMS1
319 */
320HWTEST_F(BitfieldPropertyTest, SetSubBits, TestSize.Level1)
321{
322    TestFlags base(TestFlagBits::FLAG1);
323    ExtTestFlags ext(ExtTestFlagBits::FLAG2);
324
325    base.SetSubBits(ext);
326    EXPECT_TRUE(base.IsSet(TestFlagBits::FLAG1));
327    EXPECT_FALSE(base.IsSet(TestFlagBits::FLAG2));
328
329    ExtTestFlags ext2 = base;
330    EXPECT_TRUE(ext2.IsSet(ExtTestFlagBits::FLAG2));
331    EXPECT_FALSE(ext2.IsSet(ExtTestFlagBits::FLAG1));
332}
333META_END_NAMESPACE()