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
16 #include <cstddef>
17
18 #include "gtest/gtest.h"
19
20 #include "core/components_ng/base/view_stack_processor.h"
21 #include "core/components_ng/pattern/pattern.h"
22 #include "core/components_ng/syntax/if_else_model_ng.h"
23 #include "core/components_v2/inspector/inspector_constants.h"
24
25 #define private public
26 #include "core/components_ng/syntax/if_else_node.h"
27 #include "test/mock/core/pipeline/mock_pipeline_context.h"
28
29 using namespace testing;
30 using namespace testing::ext;
31
32 namespace OHOS::Ace::NG {
33 namespace {
34 constexpr int32_t IF_ELSE_BRANCH_ID = 1;
35 constexpr int32_t IF_ELSE_BRANCH_ID_2 = 2;
36 constexpr int32_t IF_ELSE_CHILDREN_COUNT = 1;
37 constexpr int32_t IF_ELSE_CHILDREN_COUNT_2 = 0;
38 constexpr int32_t IF_ELSE_NODE_ID = 1;
39 std::list<int32_t> removedElmtIds;
40 constexpr bool IS_ATOMIC_NODE = false;
41 } // namespace
42
43 class IfElseSyntaxTestNg : public testing::Test {
44 public:
45 static void SetUpTestSuite();
46 static void TearDownTestSuite();
47 void SetUp() override;
48 void TearDown() override;
49 };
50
SetUpTestSuite()51 void IfElseSyntaxTestNg::SetUpTestSuite()
52 {
53 GTEST_LOG_(INFO) << "IfElseSyntaxTestNg SetUpTestCase";
54 }
55
TearDownTestSuite()56 void IfElseSyntaxTestNg::TearDownTestSuite()
57 {
58 GTEST_LOG_(INFO) << "IfElseSyntaxTestNg TearDownTestCase";
59 }
60
SetUp()61 void IfElseSyntaxTestNg::SetUp()
62 {
63 MockPipelineContext::SetUp();
64 }
65
TearDown()66 void IfElseSyntaxTestNg::TearDown()
67 {
68 MockPipelineContext::TearDown();
69 }
70
71 /**
72 * @tc.name: IfElseSyntaxCreateTest001
73 * @tc.desc: Create IfElse.
74 * @tc.type: FUNC
75 */
76 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxTest001, TestSize.Level1)
77 {
78 IfElseModelNG ifElse;
79 ifElse.Create();
80 auto ifElseNodeNode = AceType::DynamicCast<IfElseNode>(ViewStackProcessor::GetInstance()->Finish());
81 EXPECT_TRUE(ifElseNodeNode != nullptr && ifElseNodeNode->GetTag() == V2::JS_IF_ELSE_ETS_TAG);
82 }
83
84 /**
85 * @tc.name: IfElseSyntaxPopTest002
86 * @tc.desc: Create IfElse and pop it.
87 * @tc.type: FUNC
88 */
89 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxTest002, TestSize.Level1)
90 {
91 IfElseModelNG ifElse;
92 ifElse.Create();
93 ifElse.Pop();
94 // ViewStackProcessor will not pop when it's size equals 1.
95 EXPECT_FALSE(ViewStackProcessor::GetInstance()->GetMainElementNode() == nullptr);
96 }
97
98 /**
99 * @tc.name: IfElseSyntaxBranchIDTest003
100 * @tc.desc: Create IfElse and set/get branchId.
101 * @tc.type: FUNC
102 */
103 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxBranchIDTest003, TestSize.Level1)
104 {
105 IfElseModelNG ifElse;
106 ifElse.Create();
107 ifElse.SetBranchId(IF_ELSE_BRANCH_ID, removedElmtIds);
108
109 EXPECT_EQ(ifElse.GetBranchId(), IF_ELSE_BRANCH_ID);
110 auto ifElseNodeNode = AceType::DynamicCast<IfElseNode>(ViewStackProcessor::GetInstance()->Finish());
111 EXPECT_TRUE(ifElseNodeNode != nullptr && ifElseNodeNode->GetTag() == V2::JS_IF_ELSE_ETS_TAG);
112 EXPECT_EQ(ifElseNodeNode->GetBranchId(), IF_ELSE_BRANCH_ID);
113
114 /**
115 // corresponding ets code:
116 // if () {
117 // Blank()
118 // }
119 */
120 auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
121 ifElseNodeNode->AddChild(childFrameNode);
122 EXPECT_EQ(ifElseNodeNode->GetChildren().size(), IF_ELSE_CHILDREN_COUNT);
123 // ifElse node will clean its children when its branch id has changed.
124 ifElseNodeNode->SetBranchId(IF_ELSE_BRANCH_ID_2, removedElmtIds);
125 ifElseNodeNode->FlushUpdateAndMarkDirty();
126 EXPECT_EQ(ifElseNodeNode->GetChildren().size(), IF_ELSE_CHILDREN_COUNT_2);
127
128 /**
129 * @tc.steps: step1. Set branch id which is same as before.
130 * @tc.expected: OnDirtyLayoutWrapperSwap return the true only when the canvas images all have been initialized.
131 */
132 ifElseNodeNode->SetBranchId(IF_ELSE_BRANCH_ID, removedElmtIds);
133 ifElseNodeNode->FlushUpdateAndMarkDirty();
134 EXPECT_FALSE(ifElseNodeNode->branchIdChanged_);
135 }
136
137 /**
138 * @tc.name: IfElseSyntaxTest004
139 * @tc.desc: Create IfElse and invoke IsAtomicNode.
140 * @tc.type: FUNC
141 */
142 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxTest004, TestSize.Level1)
143 {
144 IfElseModelNG ifElse;
145 ifElse.Create();
146 ifElse.SetBranchId(IF_ELSE_BRANCH_ID, removedElmtIds);
147
148 auto ifElseNodeNode = AceType::DynamicCast<IfElseNode>(ViewStackProcessor::GetInstance()->Finish());
149 EXPECT_TRUE(ifElseNodeNode != nullptr && ifElseNodeNode->GetTag() == V2::JS_IF_ELSE_ETS_TAG);
150 EXPECT_EQ(ifElseNodeNode->IsAtomicNode(), IS_ATOMIC_NODE);
151 }
152
153 /**
154 * @tc.name: IfElseSyntaxBranchIDTest005
155 * @tc.desc: Create IfElse and set/get branchId in abnormal condition.
156 * @tc.type: FUNC
157 */
158 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxBranchIDTest005, TestSize.Level1)
159 {
160 IfElseModelNG ifElse;
161 ifElse.Create();
162 ifElse.SetBranchId(IF_ELSE_BRANCH_ID, removedElmtIds);
163
164 EXPECT_EQ(ifElse.GetBranchId(), IF_ELSE_BRANCH_ID);
165 auto ifElseNodeNode = AceType::DynamicCast<IfElseNode>(ViewStackProcessor::GetInstance()->Finish());
166 EXPECT_TRUE(ifElseNodeNode != nullptr && ifElseNodeNode->GetTag() == V2::JS_IF_ELSE_ETS_TAG);
167 EXPECT_EQ(ifElseNodeNode->GetBranchId(), IF_ELSE_BRANCH_ID);
168
169 /**
170 // corresponding ets code:
171 // if () {
172 // Blank()
173 // }
174 */
175 auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
176 ifElseNodeNode->AddChild(childFrameNode);
177 EXPECT_EQ(ifElseNodeNode->GetChildren().size(), IF_ELSE_CHILDREN_COUNT);
178 // ifElse node will clean its children when its branch id has changed.
179 ifElseNodeNode->SetBranchId(IF_ELSE_BRANCH_ID_2, removedElmtIds);
180 ifElseNodeNode->FlushUpdateAndMarkDirty();
181 EXPECT_EQ(ifElseNodeNode->GetChildren().size(), IF_ELSE_CHILDREN_COUNT_2);
182
183 /**
184 * @tc.steps: step1. Set branch id which is same as before.
185 * @tc.expected: OnDirtyLayoutWrapperSwap return the true only when the canvas images all have been initialized.
186 */
187 ifElseNodeNode->SetBranchId(IF_ELSE_BRANCH_ID_2, removedElmtIds);
188 ifElseNodeNode->FlushUpdateAndMarkDirty();
189 EXPECT_FALSE(ifElseNodeNode->branchIdChanged_);
190 }
191
192 /**
193 * @tc.name: IfElseSyntaxCreateTest006
194 * @tc.desc: Create IfElse with same id.
195 * @tc.type: FUNC
196 */
197 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxTest006, TestSize.Level1)
198 {
199 auto ifElseNode = IfElseNode::GetOrCreateIfElseNode(IF_ELSE_NODE_ID);
200 auto anotherIfElseNode = IfElseNode::GetOrCreateIfElseNode(IF_ELSE_NODE_ID);
201 EXPECT_TRUE(ifElseNode == anotherIfElseNode);
202 }
203
204 /**
205 * @tc.name: IfElseSyntaxCreateTest007
206 * @tc.desc: Test TryRetake function.
207 * @tc.type: FUNC
208 */
209 HWTEST_F(IfElseSyntaxTestNg, IfElseSyntaxTest007, TestSize.Level1)
210 {
211 /**
212 * @tc.steps: step1. Add a node whose id is "node1" to the disappearingChildren of ifElseNode.
213 */
214 auto ifElseNode = IfElseNode::GetOrCreateIfElseNode(IF_ELSE_NODE_ID);
215 ASSERT_NE(ifElseNode, nullptr);
216 auto frameNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
217 ASSERT_NE(frameNode, nullptr);
218 ASSERT_NE(frameNode->GetLayoutProperty(), nullptr);
219 frameNode->UpdateInspectorId("node1");
220 auto frameNode2 = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
221 ASSERT_NE(frameNode2, nullptr);
222 ASSERT_NE(frameNode2->GetLayoutProperty(), nullptr);
223 frameNode2->UpdateInspectorId("node2");
224 ifElseNode->branchId_ = 0;
225 ifElseNode->AddDisappearingChild(frameNode, -1, 0);
226 ifElseNode->branchId_ = 1;
227 ifElseNode->AddDisappearingChild(frameNode2, -1, 1);
228
229 /**
230 * @tc.steps: step2. IfElse is branch 0 again. Try to reuse "node1".
231 * @tc.expected: node1 can be reused, return value is true.
232 */
233 ifElseNode->branchId_ = 0;
234 bool result1 = ifElseNode->TryRetake("node1");
235 EXPECT_TRUE(result1);
236 EXPECT_TRUE(ifElseNode->GetChildren().size() == 1 && ifElseNode->GetChildAtIndex(0) == frameNode);
237
238 /**
239 * @tc.steps: step3. Try to reuse "node10".
240 * @tc.expected: node10 is not in disappearingChildren so it can't be reused, return value is false.
241 */
242 bool result2 = ifElseNode->TryRetake("node10");
243 EXPECT_FALSE(result2);
244
245 /**
246 * @tc.steps: step4. Try to reuse "node2".
247 * @tc.expected: node2 branch is not same with branchId of ifElse, return value is false.
248 */
249 bool result3 = ifElseNode->TryRetake("node2");
250 EXPECT_FALSE(result3);
251 }
252 } // namespace OHOS::Ace::NG
253