1 /* 2 * Copyright (c) 2025 iSoftStone Information Technology (Group) 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 <optional> 17 18 #include "gtest/gtest.h" 19 #include "test/mock/core/pattern/mock_pattern.h" 20 #include "test/mock/core/pipeline/mock_pipeline_context.h" 21 22 #include "core/components_ng/base/ui_node.h" 23 #include "core/components_ng/pattern/waterflow/water_flow_pattern.h" 24 #include "core/components_ng/syntax/lazy_for_each_node.h" 25 #include "core/interfaces/native/node/node_adapter_impl.h" 26 #include "core/interfaces/arkoala/arkoala_api.h" 27 28 using namespace testing; 29 using namespace testing::ext; 30 31 namespace OHOS::Ace::NG { 32 namespace { 33 class TestNode : public UINode { 34 DECLARE_ACE_TYPE(TestNode, UINode); 35 36 public: CreateTestNode(int32_t nodeId)37 static RefPtr<TestNode> CreateTestNode(int32_t nodeId) 38 { 39 auto node = MakeRefPtr<TestNode>(nodeId); 40 return node; 41 } 42 IsAtomicNode() const43 bool IsAtomicNode() const override 44 { 45 return true; 46 } 47 TestNode(int32_t nodeId)48 explicit TestNode(int32_t nodeId) : UINode("TestNode", nodeId) {} 49 ~TestNode() override = default; 50 }; 51 } 52 class NodeAdapterImplTest : public testing::Test { 53 public: SetUpTestSuite()54 static void SetUpTestSuite() 55 { 56 MockPipelineContext::SetUp(); 57 } TearDownTestSuite()58 static void TearDownTestSuite() 59 { 60 MockPipelineContext::TearDown(); 61 } 62 }; 63 64 /** 65 * @tc.name: AttachHostNode001 66 * @tc.desc: handle is null, AttachHostNode return true. 67 * @tc.type: FUNC 68 */ 69 HWTEST_F(NodeAdapterImplTest, AttachHostNode001, TestSize.Level1) 70 { 71 /** 72 * @tc.steps1 Create a frameNode. 73 */ 74 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 75 ASSERT_NE(node, nullptr); 76 ArkUINodeAdapterHandle handle = nullptr; 77 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false); 78 ASSERT_NE(frameNode1, nullptr); 79 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 80 /** 81 * @tc.steps2: handle is null, the result is true. 82 * @tc.expected: true 83 */ 84 auto attachResult = node->attachHostNode(handle, host); 85 EXPECT_TRUE(attachResult); 86 } 87 88 /** 89 * @tc.name: AttachHostNode002 90 * @tc.desc: host is null, AttachHostNode return true. 91 * @tc.type: FUNC 92 */ 93 HWTEST_F(NodeAdapterImplTest, AttachHostNode002, TestSize.Level1) 94 { 95 /** 96 * @tc.steps1 Create a handle. 97 */ 98 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 99 ASSERT_NE(node, nullptr); 100 ArkUINodeAdapterHandle handle = node->create(); 101 ArkUINodeHandle host = nullptr; 102 103 /** 104 * @tc.steps2: handle is null, the result is true. 105 * @tc.expected: true 106 */ 107 auto attachResult = node->attachHostNode(handle, host); 108 EXPECT_TRUE(attachResult); 109 } 110 111 /** 112 * @tc.name: AttachHostNode003 113 * @tc.desc: OnAttachAdapter return true, AttachHostNode return true. 114 * @tc.type: FUNC 115 */ 116 HWTEST_F(NodeAdapterImplTest, AttachHostNode003, TestSize.Level1) 117 { 118 /** 119 * @tc.steps1 Create a handle. 120 */ 121 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 122 ASSERT_NE(node, nullptr); 123 ArkUINodeAdapterHandle handle = node->create(); 124 auto frameNode1 = FrameNode::GetOrCreateFrameNode( __anon27b6e8240202() 125 V2::WATERFLOW_ETS_TAG, 2, []() { return AceType::MakeRefPtr<WaterFlowPattern>(); }); 126 ASSERT_NE(frameNode1, nullptr); 127 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 128 129 /** 130 * @tc.steps2: OnAttachAdapter return true, the result is true. 131 * @tc.expected: true 132 */ 133 auto attachResult = node->attachHostNode(handle, host); 134 EXPECT_TRUE(attachResult); 135 } 136 137 /** 138 * @tc.name: AttachHostNode004 139 * @tc.desc: OnAttachAtapper returns true, frameNode has no child node, and AttachHostNode returns false. 140 * @tc.type: FUNC 141 */ 142 HWTEST_F(NodeAdapterImplTest, AttachHostNode004, TestSize.Level1) 143 { 144 /** 145 * @tc.steps1 Create a handle. 146 */ 147 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 148 ASSERT_NE(node, nullptr); 149 ArkUINodeAdapterHandle handle = node->create(); 150 auto frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 151 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 152 153 /** 154 * @tc.steps2: OnAttachAtapper is true, frameNode has no child node. 155 * @tc.expected: true 156 */ 157 auto attachResult = node->attachHostNode(handle, host); 158 EXPECT_TRUE(attachResult); 159 } 160 161 /** 162 * @tc.name: AttachHostNode005 163 * @tc.desc: OnAttachAtapper returns true, frameNode has child node, and AttachHostNode returns false. 164 * @tc.type: FUNC 165 */ 166 HWTEST_F(NodeAdapterImplTest, AttachHostNode005, TestSize.Level1) 167 { 168 /** 169 * @tc.steps1 Create a handle. 170 */ 171 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 172 ASSERT_NE(node, nullptr); 173 ArkUINodeAdapterHandle handle = node->create(); 174 RefPtr<FrameNode> frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 175 RefPtr<FrameNode> frameNode2 = FrameNode::CreateFrameNode("child1", 2, AceType::MakeRefPtr<Pattern>()); 176 frameNode1->AddChild(frameNode2); 177 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 178 179 /** 180 * @tc.steps2: OnAttachAtapper is true, frameNode has child node. 181 * @tc.expected: false 182 */ 183 auto attachResult = node->attachHostNode(handle, host); 184 EXPECT_FALSE(attachResult); 185 } 186 187 /** 188 * @tc.name: AttachHostNode006 189 * @tc.desc: OnAttachAtapper returns false, frameNode has child exist lazyForEach node. 190 * @tc.type: FUNC 191 */ 192 HWTEST_F(NodeAdapterImplTest, AttachHostNode006, TestSize.Level1) 193 { 194 /** 195 * @tc.steps1 Create a handle. 196 */ 197 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 198 ASSERT_NE(node, nullptr); 199 ArkUINodeAdapterHandle handle = node->create(); 200 RefPtr<FrameNode> frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 201 RefPtr<UINode> frameNode2 = NG::LazyForEachNode::CreateLazyForEachNode(2, nullptr); 202 frameNode1->AddChild(frameNode2); 203 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 204 205 /** 206 * @tc.steps2: OnAttachAtapper is false, frameNode child exist lazyForEach node. 207 * @tc.expected: false 208 */ 209 auto attachResult = node->attachHostNode(handle, host); 210 EXPECT_FALSE(attachResult); 211 } 212 213 /** 214 * @tc.name: DetachHostNode001 215 * @tc.desc: host is null, DetachHostNode does not perform any operations. 216 * @tc.type: FUNC 217 */ 218 HWTEST_F(NodeAdapterImplTest, DetachHostNode001, TestSize.Level1) 219 { 220 /** 221 * @tc.steps1 Create a frameNode. 222 */ 223 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 224 ASSERT_NE(node, nullptr); 225 ArkUINodeHandle host = nullptr; 226 /** 227 * @tc.steps2: handle is null, the result is true. 228 * @tc.expected: true 229 */ 230 node->detachHostNode(host); 231 } 232 233 /** 234 * @tc.name: DetachHostNode002 235 * @tc.desc: When the child node LazyForEach, DetachHostNode moves out the child node. 236 * @tc.type: FUNC 237 */ 238 HWTEST_F(NodeAdapterImplTest, DetachHostNode002, TestSize.Level1) 239 { 240 /** 241 * @tc.steps1 Create a frameNode. 242 */ 243 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 244 ASSERT_NE(node, nullptr); 245 ArkUINodeAdapterHandle handle = node->create(); 246 ASSERT_NE(handle, nullptr); 247 RefPtr<FrameNode> frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 248 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 249 /** 250 * @tc.steps2: OnAttachAtapper. 251 * @tc.expected: true 252 */ 253 auto attachResult = node->attachHostNode(handle, host); 254 EXPECT_TRUE(attachResult); 255 /** 256 * @tc.steps3: DetachHostNode. 257 * @tc.expected: DetachHostNode moves out the child node. 258 */ 259 node->detachHostNode(host); 260 } 261 262 /** 263 * @tc.name: DetachHostNode003 264 * @tc.desc: When the child node is not LazyForEach, DetachHostNode do nothing. 265 * @tc.type: FUNC 266 */ 267 HWTEST_F(NodeAdapterImplTest, DetachHostNode003, TestSize.Level1) 268 { 269 /** 270 * @tc.steps1 Create a frameNode. 271 */ 272 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 273 ASSERT_NE(node, nullptr); 274 ArkUINodeAdapterHandle handle = node->create(); 275 ASSERT_NE(handle, nullptr); 276 RefPtr<FrameNode> frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 277 RefPtr<FrameNode> frameNode2 = FrameNode::CreateFrameNode("child1", 2, AceType::MakeRefPtr<Pattern>()); 278 frameNode1->AddChild(frameNode2); 279 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 280 /** 281 * @tc.steps2: DetachHostNode. 282 * @tc.expected: DetachHostNode not moves out the child node. 283 */ 284 node->detachHostNode(host); 285 } 286 287 /** 288 * @tc.name: DetachHostNode004 289 * @tc.desc: The first node is not a FrameNode, DetachHostNode do nothing. 290 * @tc.type: FUNC 291 */ 292 HWTEST_F(NodeAdapterImplTest, DetachHostNode004, TestSize.Level1) 293 { 294 /** 295 * @tc.steps1 Create a frameNode. 296 */ 297 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 298 ASSERT_NE(node, nullptr); 299 ArkUINodeAdapterHandle handle = node->create(); 300 ASSERT_NE(handle, nullptr); 301 auto testNode = TestNode::CreateTestNode(1); 302 RefPtr<UINode> frameNode2 = NG::LazyForEachNode::CreateLazyForEachNode(2, nullptr); 303 testNode->AddChild(frameNode2); 304 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(testNode)); 305 /** 306 * @tc.steps2: OnAttachAtapper. 307 * @tc.expected: true 308 */ 309 auto attachResult = node->attachHostNode(handle, host); 310 EXPECT_FALSE(attachResult); 311 /** 312 * @tc.steps3: DetachHostNode. 313 * @tc.expected: DetachHostNode do nothing. 314 */ 315 node->detachHostNode(host); 316 } 317 318 /** 319 * @tc.name: GetNodeAdapter002 320 * @tc.desc: When the child node LazyForEach, return hostHandle. 321 * @tc.type: FUNC 322 */ 323 HWTEST_F(NodeAdapterImplTest, GetNodeAdapter002, TestSize.Level1) 324 { 325 /** 326 * @tc.steps1 Create a frameNode. 327 */ 328 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 329 ASSERT_NE(node, nullptr); 330 ArkUINodeAdapterHandle handle = node->create(); 331 ASSERT_NE(handle, nullptr); 332 RefPtr<FrameNode> frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 333 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 334 /** 335 * @tc.steps2: OnAttachAtapper. 336 * @tc.expected: true 337 */ 338 auto attachResult = node->attachHostNode(handle, host); 339 EXPECT_TRUE(attachResult); 340 /** 341 * @tc.steps3: GetNodeAdapter. 342 * @tc.expected: GetNodeAdapter hostHandle. 343 */ 344 auto hostHandle = node->getNodeAdapter(host); 345 EXPECT_EQ(hostHandle, handle); 346 } 347 348 /** 349 * @tc.name: GetNodeAdapter003 350 * @tc.desc: When the child node not is LazyForEach, return hostHandle nullptr. 351 * @tc.type: FUNC 352 */ 353 HWTEST_F(NodeAdapterImplTest, GetNodeAdapter003, TestSize.Level1) 354 { 355 /** 356 * @tc.steps1 Create a frameNode. 357 */ 358 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 359 ASSERT_NE(node, nullptr); 360 ArkUINodeAdapterHandle handle = node->create(); 361 ASSERT_NE(handle, nullptr); 362 RefPtr<FrameNode> frameNode1 = FrameNode::CreateFrameNode("parent", 1, AceType::MakeRefPtr<Pattern>()); 363 RefPtr<FrameNode> frameNode2 = FrameNode::CreateFrameNode("child1", 2, AceType::MakeRefPtr<Pattern>()); 364 frameNode1->AddChild(frameNode2); 365 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 366 /** 367 * @tc.steps2: GetNodeAdapter. 368 * @tc.expected: nullptr. 369 */ 370 auto hostHandle = node->getNodeAdapter(host); 371 EXPECT_EQ(hostHandle, nullptr); 372 } 373 374 /** 375 * @tc.name: GetNodeAdapter004 376 * @tc.desc: When the child node not is LazyForEach, return hostHandle nullptr. 377 * @tc.type: FUNC 378 */ 379 HWTEST_F(NodeAdapterImplTest, GetNodeAdapter004, TestSize.Level1) 380 { 381 /** 382 * @tc.steps1 Create a frameNode. 383 */ 384 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 385 ASSERT_NE(node, nullptr); 386 ArkUINodeAdapterHandle handle = node->create(); 387 ASSERT_NE(handle, nullptr); 388 auto testNode = TestNode::CreateTestNode(1); 389 RefPtr<UINode> frameNode2 = NG::LazyForEachNode::CreateLazyForEachNode(2, nullptr); 390 testNode->AddChild(frameNode2); 391 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(testNode)); 392 /** 393 * @tc.steps2: OnAttachAtapper. 394 * @tc.expected: true 395 */ 396 auto attachResult = node->attachHostNode(handle, host); 397 EXPECT_FALSE(attachResult); 398 /** 399 * @tc.steps3: GetNodeAdapter. 400 * @tc.expected: nullptr. 401 */ 402 auto hostHandle = node->getNodeAdapter(host); 403 EXPECT_EQ(hostHandle, nullptr); 404 } 405 406 /** 407 * @tc.name: GetNodeTypeInNodeAdapter001 408 * @tc.desc: Check get node type from node adapter. 409 * @tc.type: FUNC 410 */ 411 HWTEST_F(NodeAdapterImplTest, GetNodeTypeInNodeAdapter001, TestSize.Level1) 412 { 413 /** 414 * @tc.steps1 Create a frameNode. 415 */ 416 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 417 ASSERT_NE(node, nullptr); 418 ArkUINodeAdapterHandle handle = node->create(); 419 ASSERT_NE(handle, nullptr); 420 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false); 421 ASSERT_NE(frameNode1, nullptr); 422 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 423 /** 424 * @tc.steps2: GetNodeTypeInNodeAdapter. 425 * @tc.expected: "". 426 */ 427 std::string tag = node->getNodeType(handle); 428 EXPECT_EQ(tag, ""); 429 /** 430 * @tc.steps3: GetNodeTypeInNodeAdapter. 431 * @tc.expected: "LazyForEach". 432 */ 433 auto attachResult = node->attachHostNode(handle, host); 434 EXPECT_TRUE(attachResult); 435 tag = node->getNodeType(handle); 436 EXPECT_EQ(tag, "LazyForEach"); 437 } 438 439 /** 440 * @tc.name: FireArkUIObjectLifecycleCallback001 441 * @tc.desc: Check fire arkui object life cycle callback. 442 * @tc.type: FUNC 443 */ 444 HWTEST_F(NodeAdapterImplTest, FireArkUIObjectLifecycleCallback001, TestSize.Level1) 445 { 446 /** 447 * @tc.steps1 Create a frameNode. 448 */ 449 const ArkUINodeAdapterAPI* node = NodeAdapter::GetNodeAdapterAPI(); 450 ASSERT_NE(node, nullptr); 451 ArkUINodeAdapterHandle handle = node->create(); 452 ASSERT_NE(handle, nullptr); 453 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false); 454 ASSERT_NE(frameNode1, nullptr); 455 ArkUINodeHandle host = reinterpret_cast<ArkUINodeHandle>(Referenced::RawPtr(frameNode1)); 456 /** 457 * @tc.steps2: FireArkUIObjectLifecycleCallback. 458 * @tc.expected: taskExecuted true. 459 */ 460 auto attachResult = node->attachHostNode(handle, host); 461 EXPECT_TRUE(attachResult); 462 auto mockPipeline = NG::MockPipelineContext::GetCurrent(); 463 ASSERT_NE(mockPipeline, nullptr); 464 bool taskExecuted = false; __anon27b6e8240302(void*) 465 mockPipeline->RegisterArkUIObjectLifecycleCallback([&taskExecuted](void*) { taskExecuted = true; }); 466 node->fireArkUIObjectLifecycleCallback(reinterpret_cast<void*>(new int), handle); 467 EXPECT_TRUE(taskExecuted); 468 } 469 } // namespace OHOS::Ace::NG 470