1 /* 2 * Copyright (c) 2022 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 #include "gtest/gtest.h" 16 17 #define protected public 18 #define private public 19 20 #include "test/mock/base/mock_task_executor.h" 21 #include "test/mock/core/common/mock_container.h" 22 #include "test/mock/core/pipeline/mock_pipeline_context.h" 23 24 #include "core/components_ng/base/group_node.h" 25 #include "core/components_ng/base/view_stack_processor.h" 26 #include "core/components_ng/pattern/pattern.h" 27 #include "core/components_ng/pattern/root/root_pattern.h" 28 29 using namespace testing; 30 using namespace testing::ext; 31 32 namespace OHOS::Ace::NG { 33 namespace { 34 constexpr char TAG_ROOT[] = "root"; 35 constexpr char TAG_CHILD[] = "child"; 36 const auto MOCK_PATTERN_ROOT = AceType::MakeRefPtr<Pattern>(); 37 const auto MOCK_PATTERN_CHILD = AceType::MakeRefPtr<Pattern>(); 38 const auto PATTERN_ROOT = AceType::MakeRefPtr<Pattern>(); 39 const auto FRAME_NODE_ROOT = FrameNode::CreateFrameNode(TAG_ROOT, 1, MOCK_PATTERN_ROOT, true); 40 const auto FRAME_NODE_CHILD = FrameNode::CreateFrameNode(TAG_CHILD, 2, MOCK_PATTERN_ROOT, false); 41 }; // namespace 42 43 class ViewStackProcessorTestNg : public testing::Test { 44 public: SetUpTestSuite()45 static void SetUpTestSuite() 46 { 47 MockPipelineContext::SetUp(); 48 MockContainer::SetUp(); 49 MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>(); 50 MockContainer::Current()->pipelineContext_ = MockPipelineContext::GetCurrentContext(); 51 MockContainer::Current()->pipelineContext_->taskExecutor_ = MockContainer::Current()->taskExecutor_; 52 } TearDownTestSuite()53 static void TearDownTestSuite() 54 { 55 MockPipelineContext::TearDown(); 56 MockContainer::TearDown(); 57 } 58 }; 59 60 /** 61 * @tc.name: ViewStackProcessorTestNg001 62 * @tc.desc: Test the operation of view stack processor 63 * @tc.type: FUNC 64 */ 65 HWTEST_F(ViewStackProcessorTestNg, ViewStackProcessorTestNg001, TestSize.Level1) 66 { 67 /** 68 * @tc.steps: step1. push isCustomView = false 69 * @tc.expected: removeSilently_ is false 70 */ 71 bool customViews[2] = { true, false }; 72 for (int i = 0; i < 2; ++i) { 73 ViewStackProcessor::GetInstance()->Push(FRAME_NODE_ROOT, customViews[i]); 74 auto node = ViewStackProcessor::GetInstance()->Finish(); 75 EXPECT_FALSE(node->removeSilently_); 76 } 77 } 78 79 /** 80 * @tc.name: ViewStackProcessorTestNg002 81 * @tc.desc: Test the operation of view stack processor 82 * @tc.type: FUNC 83 */ 84 HWTEST_F(ViewStackProcessorTestNg, ViewStackProcessorTestNg002, TestSize.Level1) 85 { 86 /** 87 * @tc.steps: step1. push childFrameNode 88 * @tc.expected: mainFrameNode's tag is child 89 */ 90 ViewStackProcessor::GetInstance()->Push(FRAME_NODE_CHILD); 91 ViewStackProcessor::GetInstance()->Push(FRAME_NODE_ROOT); 92 ViewStackProcessor::GetInstance()->ImplicitPopBeforeContinue(); 93 auto topFrameNodeOne = ViewStackProcessor::GetInstance()->GetMainElementNode(); 94 EXPECT_EQ(strcmp(topFrameNodeOne->GetTag().c_str(), TAG_CHILD), 0); 95 /** 96 * @tc.steps: step2. ImplicitPopBeforeContinue 97 * @tc.expected: mainFrameNode's tag is child 98 */ 99 ViewStackProcessor::GetInstance()->ImplicitPopBeforeContinue(); 100 auto topFrameNodeTwo = ViewStackProcessor::GetInstance()->Finish(); 101 EXPECT_EQ(strcmp(topFrameNodeTwo->GetTag().c_str(), TAG_CHILD), 0); 102 } 103 104 /** 105 * @tc.name: ViewStackProcessorTestNg003 106 * @tc.desc: Test the operation of view stack processor 107 * @tc.type: FUNC 108 */ 109 HWTEST_F(ViewStackProcessorTestNg, ViewStackProcessorTestNg003, TestSize.Level1) 110 { 111 /** 112 * @tc.steps: step1. ImplicitPopBeforeContinue 113 * @tc.expected: frameNode's isMeasureBoundary_ is false 114 */ 115 ViewStackProcessor::GetInstance()->Push(FRAME_NODE_ROOT); 116 ViewStackProcessor::GetInstance()->FlushImplicitAnimation(); 117 FRAME_NODE_ROOT->onMainTree_ = true; 118 ViewStackProcessor::GetInstance()->FlushImplicitAnimation(); 119 ViewStackProcessor::GetInstance()->FlushRerenderTask(); 120 ViewStackProcessor::GetInstance()->Push(FRAME_NODE_ROOT); 121 ViewStackProcessor::GetInstance()->FlushRerenderTask(); 122 ViewStackProcessor::GetInstance()->FlushRerenderTask(); 123 EXPECT_FALSE(FRAME_NODE_ROOT->isMeasureBoundary_); 124 } 125 126 /** 127 * @tc.name: ViewStackProcessorTestNg004 128 * @tc.desc: Test the operation of view stack processor 129 * @tc.type: FUNC 130 */ 131 HWTEST_F(ViewStackProcessorTestNg, ViewStackProcessorTestNg004, TestSize.Level1) 132 { 133 /** 134 * @tc.steps: step1. push key one and two 135 * @tc.expected: GetKey is "one_two" 136 */ 137 const std::string keyOne("one"); 138 const std::string keyTwo("two"); 139 ViewStackProcessor::GetInstance()->PushKey(keyOne); 140 ViewStackProcessor::GetInstance()->PushKey(keyTwo); 141 EXPECT_EQ(strcmp(ViewStackProcessor::GetInstance()->GetKey().c_str(), "one_two"), 0); 142 /** 143 * @tc.steps: step2. pop key one and two 144 * @tc.expected: GetKey is "" 145 */ 146 ViewStackProcessor::GetInstance()->PopKey(); 147 ViewStackProcessor::GetInstance()->PopKey(); 148 EXPECT_EQ(strcmp(ViewStackProcessor::GetInstance()->GetKey().c_str(), ""), 0); 149 ViewStackProcessor::GetInstance()->ProcessViewId("three"); 150 EXPECT_EQ(strcmp(ViewStackProcessor::GetInstance()->GetKey().c_str(), ""), 0); 151 /** 152 * @tc.steps: step3. push a empty key and do pop key 153 * @tc.expected: GetKey is "" 154 */ 155 ViewStackProcessor::GetInstance()->PushKey(""); 156 ViewStackProcessor::GetInstance()->PopKey(); 157 EXPECT_EQ(strcmp(ViewStackProcessor::GetInstance()->GetKey().c_str(), ""), 0); 158 /** 159 * @tc.steps: step4. create ScopedViewStackProcessor 160 * @tc.expected: not nullptr 161 */ 162 auto scoped = std::make_shared<ScopedViewStackProcessor>(); 163 EXPECT_NE(scoped->instance_, nullptr); 164 scoped = nullptr; 165 } 166 167 /** 168 * @tc.name: ViewStackProcessorTestNg005 169 * @tc.desc: Test the SetVisualState and GetVisualState in view stack processor 170 * @tc.type: FUNC 171 */ 172 HWTEST_F(ViewStackProcessorTestNg, ViewStackProcessorTestNg005, TestSize.Level1) 173 { 174 /** 175 * @tc.steps: step1. get instance and set different states and show result 176 * @tc.expected: GetVisualState value meeting expectations. 177 */ 178 auto instance = ViewStackProcessor::GetInstance(); 179 instance->SetVisualState(VisualState::DISABLED); 180 EXPECT_EQ(instance->GetVisualState(), 4); 181 instance->SetVisualState(VisualState::FOCUSED); 182 EXPECT_EQ(instance->GetVisualState(), 2); 183 instance->SetVisualState(VisualState::PRESSED); 184 EXPECT_EQ(instance->GetVisualState(), 1); 185 instance->SetVisualState(VisualState::NORMAL); 186 EXPECT_EQ(instance->GetVisualState(), 0); 187 instance->SetVisualState(VisualState::HOVER); 188 EXPECT_EQ(instance->GetVisualState(), 0); 189 /** 190 * @tc.steps: step2. clear visual state 191 * @tc.expected: IsCurrentVisualStateProcess meeting expectations. 192 */ 193 EXPECT_FALSE(instance->IsCurrentVisualStateProcess()); 194 instance->ClearVisualState(); 195 EXPECT_TRUE(instance->IsCurrentVisualStateProcess()); 196 } 197 198 /** 199 * @tc.name: ViewStackProcessorTestNg006 200 * @tc.desc: Test the Push and PopContainer in view stack processor 201 * @tc.type: FUNC 202 */ 203 HWTEST_F(ViewStackProcessorTestNg, ViewStackProcessorTestNg006, TestSize.Level1) 204 { 205 /** 206 * @tc.steps: step1. Get instance and try PopContainer 207 * @tc.expected: actually nothing happened because elementsStack no value. 208 */ 209 auto instance = ViewStackProcessor::GetInstance(); 210 instance->PopContainer(); 211 EXPECT_EQ(instance->elementsStack_.size(), 0); 212 /** 213 * @tc.steps: step2. Create some node 214 */ 215 auto pipe = MockPipelineContext::GetCurrent(); 216 const auto root = FrameNode::CreateFrameNode(TAG_CHILD, 0, AceType::MakeRefPtr<RootPattern>(), true); 217 const auto child = FrameNode::CreateFrameNode(TAG_CHILD, 3, AceType::MakeRefPtr<RootPattern>(), true); 218 const auto child2 = FrameNode::CreateFrameNode(TAG_CHILD, 4, AceType::MakeRefPtr<Pattern>(), true); 219 root->context_ = AceType::RawPtr(pipe); 220 child->context_ = AceType::RawPtr(pipe); 221 child2->context_ = AceType::RawPtr(pipe); 222 /** 223 * @tc.steps: step3. Push root into container 224 * @tc.expected: Pop failed elementsStack_ size still 1. 225 */ 226 instance->Push(root); 227 instance->PopContainer(); 228 EXPECT_EQ(instance->elementsStack_.size(), 1); 229 /** 230 * @tc.steps: step4. pop root and put FRAME_NODE_ROOT into container 231 * @tc.expected: Pop failed elementsStack_ size still 1. 232 */ 233 FRAME_NODE_ROOT->context_ = AceType::RawPtr(pipe); 234 instance->elementsStack_.pop(); 235 instance->Push(FRAME_NODE_ROOT); 236 instance->PopContainer(); 237 EXPECT_EQ(instance->elementsStack_.size(), 1); 238 /** 239 * @tc.steps: step5. push child2 and child into instance 240 * @tc.expected: Pop success elementsStack_ size residue 1. 241 */ 242 instance->Push(child2); 243 instance->Push(child); 244 instance->ImplicitPopBeforeContinue(); 245 EXPECT_EQ(instance->elementsStack_.size(), 2); 246 instance->PopContainer(); 247 EXPECT_EQ(instance->elementsStack_.size(), 1); 248 /** 249 * @tc.steps: step6. push child2 again 250 * @tc.expected: Pop success elementsStack_ size residue 1. 251 */ 252 instance->Push(child2); 253 instance->PopContainer(); 254 EXPECT_EQ(instance->elementsStack_.size(), 1); 255 } 256 } // namespace OHOS::Ace::NG 257