• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstddef>
17 
18 #include "gtest/gtest.h"
19 
20 #include "core/interfaces/native/node/node_content_modifier.h"
21 #define private public
22 #include "interfaces/native/native_node.h"
23 #include "test/mock/core/pipeline/mock_pipeline_context.h"
24 
25 #include "base/memory/ace_type.h"
26 #include "core/components_ng/base/ui_node.h"
27 #include "core/components_ng/base/view_stack_processor.h"
28 #include "core/components_ng/syntax/content_slot_model_ng.h"
29 #include "core/components_ng/syntax/content_slot_node.h"
30 #include "core/components_ng/syntax/node_content.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace OHOS::Ace::NG {
36 namespace {
37 constexpr int32_t NODE_CONTENT_INIT_STATUS = 1000;
38 constexpr int32_t NODE_CONTENT_ATTACH_TO_TREE = 1001;
39 constexpr int32_t NODE_CONTENT_DETACH_FROM_TREE = 1002;
40 constexpr uint32_t NUM_1 = 1;
41 constexpr uint32_t NUM_2 = 2;
42 const std::string NODE_TAG = "node";
43 } // namespace
44 
45 class ContentSlotSyntaxTestNg : public testing::Test {
46 public:
47     static void SetUpTestSuite();
48     static void TearDownTestSuite();
49     void SetUp() override;
50     void TearDown() override;
51     RefPtr<NodeContent> nodeContentPtr_ = nullptr;
52 };
53 
SetUpTestSuite()54 void ContentSlotSyntaxTestNg::SetUpTestSuite()
55 {
56     GTEST_LOG_(INFO) << "ContentSlotSyntaxTestNg SetUpTestCase";
57 }
58 
TearDownTestSuite()59 void ContentSlotSyntaxTestNg::TearDownTestSuite()
60 {
61     GTEST_LOG_(INFO) << "ContentSlotSyntaxTestNg TearDownTestCase";
62 }
63 
SetUp()64 void ContentSlotSyntaxTestNg::SetUp()
65 {
66     nodeContentPtr_ = AceType::MakeRefPtr<NodeContent>();
67     MockPipelineContext::SetUp();
68 }
69 
TearDown()70 void ContentSlotSyntaxTestNg::TearDown()
71 {
72     nodeContentPtr_ = nullptr;
73     MockPipelineContext::TearDown();
74 }
75 
76 /**
77  * @tc.name: ContentSlotSyntaxTest001
78  * @tc.desc: ContentSlot For CAPI 1
79  * @tc.type: FUNC
80  */
81 HWTEST_F(ContentSlotSyntaxTestNg, ContentSlotSyntaxTest001, TestSize.Level1)
82 {
83     /**
84      * @tc.steps: step1. Create contentSlotNode
85      * @tc.expected: contentSlotNode create successfully
86      */
87     NodeContent* nodeContent = AceType::RawPtr(nodeContentPtr_);
88     ASSERT_NE(nodeContent, nullptr);
89     ContentSlotModel::Create(nodeContent);
90     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
91     EXPECT_TRUE(contentSlotNode != nullptr && contentSlotNode->GetTag() == V2::JS_NODE_SLOT_ETS_TAG);
92 
93     /**
94      * @tc.steps: step2. add/insert/remove child
95      * @tc.expected: add/insert/remove child successfully
96      */
97     const auto* contentModifier = NodeModifier::GetNodeContentModifier();
98     auto childFrameNode1 = FrameNode::CreateFrameNode("frameNode1", -1, AceType::MakeRefPtr<Pattern>());
99     contentModifier->addChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
100         reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(childFrameNode1)));
101     auto children = contentSlotNode->GetChildren();
102     EXPECT_TRUE(children.size() == NUM_1 && children.front()->GetTag() == "frameNode1");
103 
104     auto childFrameNode2 = FrameNode::CreateFrameNode("frameNode2", -1, AceType::MakeRefPtr<Pattern>());
105     contentModifier->insertChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
106         reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(childFrameNode2)), 0);
107     children = contentSlotNode->GetChildren();
108     EXPECT_TRUE(children.size() == NUM_2 && children.front()->GetTag() == "frameNode2");
109 
110     contentModifier->removeChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
111         reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(childFrameNode1)));
112     contentModifier->removeChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
113         reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(childFrameNode2)));
114     children = contentSlotNode->GetChildren();
115     EXPECT_TRUE(children.size() == 0);
116 }
117 
118 /**
119  * @tc.name: ContentSlotSyntaxTest002
120  * @tc.desc: ContentSlot For CAPI 2
121  * @tc.type: FUNC
122  */
123 HWTEST_F(ContentSlotSyntaxTestNg, ContentSlotSyntaxTest002, TestSize.Level1)
124 {
125     /**
126      * @tc.steps: step1. Create contentSlotNode
127      * @tc.expected: contentSlotNode create successfully
128      */
129     NodeContent* nodeContent = AceType::RawPtr(nodeContentPtr_);
130     ASSERT_NE(nodeContent, nullptr);
131     ContentSlotModel::Create(nodeContent);
132     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
133     EXPECT_TRUE(contentSlotNode != nullptr && contentSlotNode->GetTag() == V2::JS_NODE_SLOT_ETS_TAG);
134 
135     /**
136      * @tc.steps: step2. releated to event
137      * @tc.expected: registerEvent, set/getUserData, getNodeContent successfully
138      */
139     const auto* contentModifier = NodeModifier::GetNodeContentModifier();
140     auto* userData = new int32_t(NODE_CONTENT_INIT_STATUS);
141     contentModifier->setUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), userData);
__anon5b34169b0202(ArkUINodeContentEvent* event) 142     auto callback = [](ArkUINodeContentEvent* event) {
143         auto* nodeContent = event->nodeContent;
144         const auto* contentModifier = NodeModifier::GetNodeContentModifier();
145         if (event->type == 0) {
146             int32_t* userData = reinterpret_cast<int32_t*>(
147                 contentModifier->getUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent)));
148             EXPECT_EQ(*userData, NODE_CONTENT_INIT_STATUS);
149             delete userData;
150             userData = new int32_t(NODE_CONTENT_ATTACH_TO_TREE);
151             contentModifier->setUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), userData);
152         } else if (event->type == 1) {
153             int32_t* userData = reinterpret_cast<int32_t*>(
154                 contentModifier->getUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent)));
155             EXPECT_EQ(*userData, NODE_CONTENT_ATTACH_TO_TREE);
156             delete userData;
157             userData = new int32_t(NODE_CONTENT_DETACH_FROM_TREE);
158             contentModifier->setUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), userData);
159         }
160     };
161     contentModifier->registerEvent(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), nullptr, std::move(callback));
162     nodeContent->OnAttachToMainTree();
163     EXPECT_TRUE(nodeContent->onMainTree_);
164     nodeContent->OnDetachFromMainTree();
165     EXPECT_FALSE(nodeContent->onMainTree_);
166     userData =
167         reinterpret_cast<int32_t*>(contentModifier->getUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent)));
168     EXPECT_EQ(*userData, NODE_CONTENT_DETACH_FROM_TREE);
169     delete userData;
170 }
171 
172 /**
173  * @tc.name: ContentSlotSyntaxTest003
174  * @tc.desc: ContentSlot For Create
175  * @tc.type: FUNC
176  */
177 HWTEST_F(ContentSlotSyntaxTestNg, ContentSlotSyntaxTest003, TestSize.Level1)
178 {
179     /**
180      * @tc.steps: step1. Create contentSlotNode
181      * @tc.expected: contentSlotNode create failed
182      */
183     NodeContent* nodeContent = nullptr;
184     ContentSlotModel::Create(nodeContent);
185 
186     /**
187      * @tc.steps: step2. Create contentSlotNode
188      * @tc.expected: contentSlotNode create success
189      */
190     nodeContent = AceType::RawPtr(nodeContentPtr_);
191     ASSERT_NE(nodeContent, nullptr);
192     ContentSlotModel::Create(nodeContent);
193     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
194     ASSERT_NE(contentSlotNode, nullptr);
195     EXPECT_EQ(contentSlotNode->GetTag(), V2::JS_NODE_SLOT_ETS_TAG);
196 
197     /**
198      * @tc.steps: step3. GetOrCreateContentSlot by nodeId
199      * @tc.expected: GetOrCreateContentSlot create success
200      */
201     auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
202     auto node = contentSlotNode->GetOrCreateContentSlot(nodeId);
203     ASSERT_NE(contentSlotNode, nullptr);
204     EXPECT_EQ(node->GetId(), nodeId);
205 
206     node = contentSlotNode->GetOrCreateContentSlot(nodeId);
207     ASSERT_NE(node, nullptr);
208     EXPECT_EQ(node->GetId(), nodeId);
209 }
210 
211 /**
212  * @tc.name: AttachToNode001
213  * @tc.desc: ContentSlot for AttachToNode
214  * @tc.type: FUNC
215  */
216 HWTEST_F(ContentSlotSyntaxTestNg, AttachToNode001, TestSize.Level1)
217 {
218     /**
219      * @tc.steps: step1. Create contentSlotNode
220      * @tc.expected: contentSlotNode create success
221      */
222     auto nodeContent = AceType::RawPtr(nodeContentPtr_);
223     ASSERT_NE(nodeContent, nullptr);
224     ContentSlotModel::Create(nodeContent);
225     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
226     ASSERT_NE(contentSlotNode, nullptr);
227     EXPECT_EQ(contentSlotNode->GetTag(), V2::JS_NODE_SLOT_ETS_TAG);
228 
229     /**
230      * @tc.steps: step2. Create childNode
231      * @tc.expected: childNode create success
232      */
233     auto childNode = ViewStackProcessor::GetInstance()->GetMainElementNode();
234     ASSERT_NE(childNode, nullptr);
235     nodeContent->children_.push_back(childNode);
236     EXPECT_GT(nodeContent->children_.size(), 0);
237     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
238     nodeContent->nodeSlot_ = childNode;
239     UINode* uiNode = Referenced::RawPtr(childNode);
240     ASSERT_NE(uiNode, nullptr);
241     uiNode->onMainTree_ = true;
242 
243     /**
244      * @tc.steps: step3. AttachToNode uiNode
245      * @tc.expected: the size of children more than 0
246      */
247     nodeContent->AttachToNode(uiNode);
248     EXPECT_GT(nodeContent->children_.size(), 0);
249     nodeContent->DetachFromNode();
250 }
251 
252 /**
253  * @tc.name: AttachToNode002
254  * @tc.desc: ContentSlot for AttachToNode
255  * @tc.type: FUNC
256  */
257 HWTEST_F(ContentSlotSyntaxTestNg, AttachToNode002, TestSize.Level1)
258 {
259     /**
260      * @tc.steps: step1. Create contentSlotNode
261      * @tc.expected: contentSlotNode create success
262      */
263     auto nodeContent = AceType::RawPtr(nodeContentPtr_);
264     ASSERT_NE(nodeContent, nullptr);
265     ContentSlotModel::Create(nodeContent);
266     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
267     ASSERT_NE(contentSlotNode, nullptr);
268     EXPECT_EQ(contentSlotNode->GetTag(), V2::JS_NODE_SLOT_ETS_TAG);
269 
270     /**
271      * @tc.steps: step3. AttachToNode uiNode
272      * @tc.expected: the size of children is 0
273      */
274     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
275     nodeContent->nodeSlot_ = node;
276     auto uiNode = ViewStackProcessor::GetInstance()->GetMainElementNode();
277     ASSERT_NE(uiNode, nullptr);
278     nodeContent->AttachToNode(AceType::RawPtr(uiNode));
279     EXPECT_EQ(nodeContent->children_.size(), 0);
280     nodeContent->DetachFromNode();
281 }
282 
283 /**
284  * @tc.name: AddNode001
285  * @tc.desc: Test for AddNode
286  * @tc.type: FUNC
287  */
288 HWTEST_F(ContentSlotSyntaxTestNg, AddNode001, TestSize.Level1)
289 {
290     /**
291      * @tc.steps: step1. Create contentSlotNode
292      * @tc.expected: contentSlotNode create success
293      */
294     auto nodeContent = AceType::RawPtr(nodeContentPtr_);
295     ASSERT_NE(nodeContent, nullptr);
296     ContentSlotModel::Create(nodeContent);
297     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
298     ASSERT_NE(contentSlotNode, nullptr);
299     EXPECT_EQ(contentSlotNode->GetTag(), V2::JS_NODE_SLOT_ETS_TAG);
300 
301     /**
302      * @tc.steps: step2. Create childNode
303      * @tc.expected: childNode create success
304      */
305     auto childNode = ViewStackProcessor::GetInstance()->GetMainElementNode();
306     ASSERT_NE(childNode, nullptr);
307     nodeContent->nodeSlot_ = childNode;
308     UINode* uiNode = Referenced::RawPtr(childNode);
309     ASSERT_NE(uiNode, nullptr);
310 
311     /**
312      * @tc.steps: step3. AddNode uiNode
313      * @tc.expected: the size of children more than 0
314      */
315     nodeContent->AddNode(uiNode, 0);
316     auto size = nodeContent->children_.size();
317     nodeContent->AddNode(uiNode, 0);
318     EXPECT_EQ(size, nodeContent->children_.size());
319     nodeContent->RemoveNode(uiNode);
320     EXPECT_EQ(nodeContent->children_.size(), size - 1);
321 }
322 
323 /**
324  * @tc.name: RemoveNode001
325  * @tc.desc: Test for RemoveNode
326  * @tc.type: FUNC
327  */
328 HWTEST_F(ContentSlotSyntaxTestNg, RemoveNode001, TestSize.Level1)
329 {
330     /**
331      * @tc.steps: step1. Create contentSlotNode
332      * @tc.expected: contentSlotNode create success
333      */
334     auto nodeContent = AceType::RawPtr(nodeContentPtr_);
335     ASSERT_NE(nodeContent, nullptr);
336     ContentSlotModel::Create(nodeContent);
337     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
338     ASSERT_NE(contentSlotNode, nullptr);
339     EXPECT_EQ(contentSlotNode->GetTag(), V2::JS_NODE_SLOT_ETS_TAG);
340 
341     /**
342      * @tc.steps: step2. Create childNode
343      * @tc.expected: childNode create success
344      */
345     auto childNode = ViewStackProcessor::GetInstance()->GetMainElementNode();
346     ASSERT_NE(childNode, nullptr);
347     nodeContent->nodeSlot_ = childNode;
348     UINode* uiNode = Referenced::RawPtr(childNode);
349     ASSERT_NE(uiNode, nullptr);
350 
351     /**
352      * @tc.steps: step3. AddNode uiNode
353      * @tc.expected: the size of children more than 0
354      */
355     nodeContent->AddNode(uiNode, 0);
356     auto size = nodeContent->children_.size();
357     EXPECT_GT(size, 0);
358 
359     /**
360      * @tc.steps: step3. remove other uiNode
361      * @tc.expected: the size of children  is no change
362      */
363     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
364     UINode* uiNodeOhter = Referenced::RawPtr(node);
365     nodeContent->RemoveNode(uiNodeOhter);
366     EXPECT_EQ(size, nodeContent->children_.size());
367 }
368 
369 /**
370  * @tc.name: OnAttachToMainTree001
371  * @tc.desc: Test for RemoveNode
372  * @tc.type: FUNC
373  */
374 HWTEST_F(ContentSlotSyntaxTestNg, OnAttachToMainTree001, TestSize.Level1)
375 {
376     /**
377      * @tc.steps: step1. Call OnAttachToMainTree and SetAttachToMainTreeCallback
378      * @tc.expected: onMainTree_ is true
379      */
380     auto nodeContent = AceType::RawPtr(nodeContentPtr_);
381     ASSERT_NE(nodeContent, nullptr);
382     ContentSlotModel::Create(nodeContent);
383     bool attachcallbackRet = false;
__anon5b34169b0302() 384     std::function<void()> attachcallback = [&attachcallbackRet]() { attachcallbackRet = true; };
385     nodeContent->SetAttachToMainTreeCallback(move(attachcallback));
386     nodeContent->OnAttachToMainTree();
387     EXPECT_TRUE(attachcallbackRet);
388     EXPECT_TRUE(nodeContent->onMainTree_);
389 
390     /**
391      * @tc.steps: step2. Call OnDetachFromMainTree and SetDetachFromMainTreeCallback
392      * @tc.expected: onMainTree_ is false
393      */
394     bool detachcallbackRet = false;
__anon5b34169b0402() 395     std::function<void()> detachcallback = [&detachcallbackRet]() { detachcallbackRet = true; };
396     nodeContent->SetDetachFromMainTreeCallback(move(detachcallback));
397     nodeContent->OnDetachFromMainTree();
398     EXPECT_TRUE(detachcallbackRet);
399     EXPECT_FALSE(nodeContent->onMainTree_);
400 }
401 } // namespace OHOS::Ace::NG