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/container/container_observer.h>
20 #include <meta/api/make_callback.h>
21 #include <meta/base/ref_uri.h>
22 
23 #include "src/test_runner.h"
24 #include "src/test_utils.h"
25 #include "src/testing_objects.h"
26 #include "src/util.h"
27 
28 using namespace testing;
29 using namespace testing::ext;
30 
31 META_BEGIN_NAMESPACE()
32 
33 class IntfContainerObserverTest : public testing::Test {
34 public:
35     void SetUp() override
36     {
37         container_ = interface_pointer_cast<IContainer>(CreateTestContainer("Base"));
38         ASSERT_NE(container_, nullptr);
39         ASSERT_NE(observer_.GetIObject(), nullptr);
40         container_->Add(CreateTestType<IObject>("Object1_1"));
41         container_->Add(CreateTestType<IObject>("SameNameDifferentUid"));
42         container_->Add(CreateTestType<IObject>("ObjectDupe"));
43         container1_1_ = interface_pointer_cast<IContainer>(CreateTestContainer("Container1_1"));
44         container_->Add(interface_pointer_cast<IObject>(container1_1_));
45         container1_1_->Add(CreateTestType<IObject>("Object2_1"));
46         container1_1_->Add(CreateTestType<IObject>("ObjectDupe"));
47         container1_1_->Add(CreateTestType<IObject>("SameNameDifferentUid"));
48         container_->Add(CreateTestType<IObject>("Object1_3"));
49         container2_1_ = interface_pointer_cast<IContainer>(CreateTestContainer("SameNameDifferentUid"));
50         container1_1_->Add(interface_pointer_cast<IObject>(container2_1_));
51 
52         observer_.Container(container_)
53             .OnDescendantAdded([this](const ChildChangedInfo& info) { OnAdded(info); })
54             .OnDescendantRemoved([this](const ChildChangedInfo& info) { OnRemoved(info); })
55             .OnDescendantMoved([this](const ChildMovedInfo& info) { OnMoved(info); });
56     }
57     void TearDown() override
58     {
59         container_.reset();
60         observer_.ResetIObject();
61     }
SetUpTestSuite()62     static void SetUpTestSuite()
63     {
64         SetTest();
65     }
TearDownTestSuite()66     static void TearDownTestSuite()
67     {
68         ResetTest();
69     }
70 
71 protected:
OnAdded(const ChildChangedInfo& info)72     void OnAdded(const ChildChangedInfo& info)
73     {
74         addedCalls_.push_back(info);
75     }
OnRemoved(const ChildChangedInfo& info)76     void OnRemoved(const ChildChangedInfo& info)
77     {
78         removedCalls_.push_back(info);
79     }
OnMoved(const ChildMovedInfo& info)80     void OnMoved(const ChildMovedInfo& info)
81     {
82         movedCalls_.push_back(info);
83     }
84 
85     BASE_NS::vector<ChildChangedInfo> addedCalls_;
86     BASE_NS::vector<ChildChangedInfo> removedCalls_;
87     BASE_NS::vector<ChildMovedInfo> movedCalls_;
88 
89     IContainer::Ptr container_;
90     IContainer::Ptr container1_1_;
91     IContainer::Ptr container2_1_;
92     META_NS::ContainerObserver observer_;
93 };
94 
95 /**
96  * @tc.name: IntfContainerObserverTest
97  * @tc.desc: test AddDirectChild function
98  * @tc.type: FUNC
99  * @tc.require: I7DMS1
100  */
HWTEST_F(IntfContainerObserverTest, AddDirectChild, TestSize.Level1)101 HWTEST_F(IntfContainerObserverTest, AddDirectChild, TestSize.Level1)
102 {
103     auto child = CreateTestType<IObject>("DirectChild");
104     ASSERT_TRUE(container_->Add(child));
105 
106     ASSERT_THAT(addedCalls_, SizeIs(1));
107     ASSERT_THAT(removedCalls_, SizeIs(0));
108     ASSERT_THAT(movedCalls_, SizeIs(0));
109 
110     auto info = addedCalls_[0];
111     EXPECT_EQ(info.object, child);
112     EXPECT_EQ(info.parent.lock(), container_);
113 }
114 
115 /**
116  * @tc.name: IntfContainerObserverTest
117  * @tc.desc: test AddDescendantChild function
118  * @tc.type: FUNC
119  * @tc.require: I7DMS1
120  */
HWTEST_F(IntfContainerObserverTest, AddDescendantChild, TestSize.Level1)121 HWTEST_F(IntfContainerObserverTest, AddDescendantChild, TestSize.Level1)
122 {
123     auto child = CreateTestType<IObject>("Descendant");
124     ASSERT_TRUE(container2_1_->Add(child));
125 
126     ASSERT_THAT(addedCalls_, SizeIs(1));
127     ASSERT_THAT(removedCalls_, SizeIs(0));
128     ASSERT_THAT(movedCalls_, SizeIs(0));
129 
130     auto info = addedCalls_[0];
131     EXPECT_EQ(info.object, child);
132     EXPECT_EQ(info.parent.lock(), container2_1_);
133 }
134 
135 /**
136  * @tc.name: IntfContainerObserverTest
137  * @tc.desc: test ChangedAfterChild function
138  * @tc.type: FUNC
139  * @tc.require: I7DMS1
140  */
HWTEST_F(IntfContainerObserverTest, ChangeAfterChild, TestSize.Level1)141 HWTEST_F(IntfContainerObserverTest, ChangeAfterChild, TestSize.Level1)
142 {
143     auto container = CreateTestContainer<IContainer>("DescendantContainer");
144     ASSERT_TRUE(container2_1_->Add(container));
145 
146     ASSERT_THAT(addedCalls_, SizeIs(1));
147     ASSERT_THAT(removedCalls_, SizeIs(0));
148     ASSERT_THAT(movedCalls_, SizeIs(0));
149 
150     auto info = addedCalls_[0];
151     EXPECT_EQ(info.object, interface_pointer_cast<IObject>(container));
152     EXPECT_EQ(info.parent.lock(), container2_1_);
153 
154     auto child = CreateTestType<IObject>("DescendantChild");
155     ASSERT_TRUE(container->Add(child));
156 
157     ASSERT_THAT(addedCalls_, SizeIs(2));
158     ASSERT_THAT(removedCalls_, SizeIs(0));
159     ASSERT_THAT(movedCalls_, SizeIs(0));
160 
161     info = addedCalls_[1];
162     EXPECT_EQ(info.object, child);
163     EXPECT_EQ(info.parent.lock(), container);
164 
165     EXPECT_TRUE(container1_1_->Remove(container2_1_));
166 
167     EXPECT_TRUE(container->Remove(child));
168     ASSERT_THAT(addedCalls_, SizeIs(2));
169     ASSERT_THAT(removedCalls_, SizeIs(1));
170     ASSERT_THAT(movedCalls_, SizeIs(0));
171 
172     info = removedCalls_[0];
173     EXPECT_EQ(info.object, interface_pointer_cast<IObject>(container2_1_));
174     EXPECT_EQ(info.parent.lock(), container1_1_);
175 }
176 
177 /**
178  * @tc.name: IntfContainerObserverTest
179  * @tc.desc: test RemoveDescendant function
180  * @tc.type: FUNC
181  * @tc.require: I7DMS1
182  */
HWTEST_F(IntfContainerObserverTest, RemoveDescendant, TestSize.Level1)183 HWTEST_F(IntfContainerObserverTest, RemoveDescendant, TestSize.Level1)
184 {
185     container_->Remove(container1_1_);
186     ASSERT_THAT(addedCalls_, SizeIs(0));
187     ASSERT_THAT(removedCalls_, SizeIs(1));
188     ASSERT_THAT(movedCalls_, SizeIs(0));
189 
190     auto info = removedCalls_[0];
191     EXPECT_EQ(info.object, interface_pointer_cast<IObject>(container1_1_));
192     EXPECT_EQ(info.parent.lock(), container_);
193     removedCalls_.clear();
194 
195     auto child = CreateTestType<IObject>("Descendant");
196     container1_1_->Add(child);
197 
198     ASSERT_THAT(addedCalls_, SizeIs(0));
199     ASSERT_THAT(removedCalls_, SizeIs(0));
200     ASSERT_THAT(movedCalls_, SizeIs(0));
201 }
202 
203 META_END_NAMESPACE()