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 <functional>
17 #include <optional>
18 
19 #include "gmock/gmock-actions.h"
20 #include "gmock/gmock-matchers.h"
21 #include "gtest/gtest.h"
22 
23 #define private public
24 #define protected public
25 #include "test/mock/base/mock_task_executor.h"
26 #include "test/mock/core/common/mock_container.h"
27 #include "test/mock/core/pipeline/mock_pipeline_context.h"
28 #include "test/mock/core/render/mock_paragraph.h"
29 #include "test/mock/core/render/mock_render_context.h"
30 #include "test/mock/core/rosen/mock_canvas.h"
31 
32 #include "core/components_ng/base/frame_node.h"
33 #include "core/components_ng/base/view_stack_processor.h"
34 #include "core/components_ng/pattern/pattern.h"
35 #include "core/components_ng/pattern/root/root_pattern.h"
36 #include "core/components_ng/pattern/symbol/constants.h"
37 #include "core/components_ng/pattern/symbol/symbol_effect_options.h"
38 #include "core/components_ng/pattern/symbol/symbol_model_ng.h"
39 #include "core/components_ng/pattern/symbol/symbol_source_info.h"
40 #include "core/components_ng/pattern/text/text_layout_property.h"
41 #include "core/components_ng/pattern/text/text_pattern.h"
42 #include "frameworks/core/components_ng/pattern/root/root_pattern.h"
43 #undef private
44 #undef protected
45 
46 using namespace testing;
47 using namespace testing::ext;
48 
49 namespace OHOS::Ace::NG {
50 
51 const std::uint32_t CREATE_VALUE = 983041;
52 const Dimension FONT_SIZE_VALUE = Dimension(20.1, DimensionUnit::PX);
53 std::uint32_t RENDER_STRATEGY = 1;
54 std::uint32_t EFFECT_STRATEGY = 1;
55 SymbolEffectOptions SYMBOL_EFFECT_OPTIONS =
56     SymbolEffectOptions(OHOS::Ace::SymbolEffectType::BOUNCE, OHOS::Ace::ScopeType::WHOLE, OHOS::Ace::CommonSubType::UP);
57 std::vector<Color> SYMBOL_COLOR_LIST = { Color::FromRGB(255, 100, 100), Color::FromRGB(255, 255, 100) };
58 
59 struct TestProperty {
60     std::optional<Dimension> fontSizeValue = std::nullopt;
61     std::optional<Ace::FontWeight> fontWeightValue = std::nullopt;
62     std::optional<SymbolSourceInfo> symbolSourceInfo = std::nullopt;
63 };
64 
65 class SymbolTestNg : public testing::Test {
66 public:
67     static void SetUpTestSuite();
68     static void TearDownTestSuite();
69     void SetUp() override;
70     void TearDown() override;
71 
72 protected:
73     static void UpdateTextLayoutProperty(RefPtr<TextLayoutProperty> textLayoutProperty);
74     RefPtr<FrameNode> symbolGlyphNode_;
75 };
76 
SetUpTestSuite()77 void SymbolTestNg::SetUpTestSuite()
78 {
79     MockPipelineContext::SetUp();
80     MockContainer::SetUp();
81     MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
82 }
83 
TearDownTestSuite()84 void SymbolTestNg::TearDownTestSuite()
85 {
86     MockPipelineContext::TearDown();
87     MockContainer::TearDown();
88 }
89 
SetUp()90 void SymbolTestNg::SetUp()
91 {
92     MockPipelineContext::SetUp();
93     MockContainer::SetUp();
94     MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
95     auto* stack = ViewStackProcessor::GetInstance();
96     auto nodeId = stack->ClaimNodeId();
97     symbolGlyphNode_ = FrameNode::GetOrCreateFrameNode(
98         V2::SYMBOL_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TextPattern>(); });
99     ASSERT_NE(symbolGlyphNode_, nullptr);
100 }
101 
TearDown()102 void SymbolTestNg::TearDown()
103 {
104     MockParagraph::TearDown();
105 }
106 
107 /**
108  * @tc.name: SymbolFrameNodeCreator001
109  * @tc.desc: test symbol create
110  * @tc.type: FUNC
111  */
112 HWTEST_F(SymbolTestNg, SymbolFrameNodeCreator001, TestSize.Level1)
113 {
114     ASSERT_NE(symbolGlyphNode_, nullptr);
115     auto textPattern = symbolGlyphNode_->GetPattern<TextPattern>();
116     ASSERT_NE(textPattern, nullptr);
117     SymbolModelNG symbolModel;
118     symbolModel.Create(CREATE_VALUE);
119     EXPECT_EQ(static_cast<int32_t>(ViewStackProcessor::GetInstance()->elementsStack_.size()), 1);
120     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
121         ViewStackProcessor::GetInstance()->elementsStack_.pop();
122     }
123 }
124 
125 /**
126  * @tc.name: SymbolFrameNodeCreator002
127  * @tc.desc: test symbol is atomicNode
128  * @tc.type: FUNC
129  */
130 HWTEST_F(SymbolTestNg, SymbolFrameNodeCreator002, TestSize.Level1)
131 {
132     ASSERT_NE(symbolGlyphNode_, nullptr);
133     auto textPattern = symbolGlyphNode_->GetPattern<TextPattern>();
134     ASSERT_NE(textPattern, nullptr);
135     ASSERT_TRUE(textPattern->IsAtomicNode());
136 }
137 
138 /**
139  * @tc.name: SymbolFrameNodeCreator003
140  * @tc.desc: test symbol unicode
141  * @tc.type: FUNC
142  */
143 HWTEST_F(SymbolTestNg, SymbolFrameNodeCreator003, TestSize.Level1)
144 {
145     /**
146      * @tc.steps: step1. create symbol node
147      */
148     SymbolModelNG symbolModelNG;
149     symbolModelNG.Create(CREATE_VALUE);
150 
151     /**
152      * @tc.steps: step2. get symbol node and layoutProperty
153      */
154     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
155     ASSERT_NE(frameNode, nullptr);
156     ASSERT_TRUE(frameNode->GetTag() == V2::SYMBOL_ETS_TAG);
157     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
158     ASSERT_NE(layoutProperty, nullptr);
159     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
160     ASSERT_NE(textLayoutProperty, nullptr);
161 
162     /**
163      * @tc.steps: step3. test get symbol unicode property
164      */
165     auto symbolInfo = textLayoutProperty->GetSymbolSourceInfo().value();
166     EXPECT_EQ(symbolInfo.GetUnicode(), CREATE_VALUE);
167 }
168 
169 /**
170  * @tc.name: SymbolPropertyTest001
171  * @tc.desc: test symbol fontSize property of symbol
172  * @tc.type: FUNC
173  */
174 HWTEST_F(SymbolTestNg, SymbolPropertyTest001, TestSize.Level1)
175 {
176     /**
177      * @tc.steps: step1. create symbol node
178      */
179     SymbolModelNG symbolModelNG;
180     symbolModelNG.Create(CREATE_VALUE);
181     symbolModelNG.SetFontSize(FONT_SIZE_VALUE);
182 
183     /**
184      * @tc.steps: step2. get symbol node and layoutProperty
185      */
186     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
187     ASSERT_NE(frameNode, nullptr);
188     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
189     ASSERT_NE(layoutProperty, nullptr);
190     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
191     ASSERT_NE(textLayoutProperty, nullptr);
192 
193     /**
194      * @tc.steps: step3. test get fontSize property
195      */
196     const std::unique_ptr<FontStyle>& symbolStyle = textLayoutProperty->GetFontStyle();
197     ASSERT_NE(symbolStyle, nullptr);
198     EXPECT_EQ(symbolStyle->GetFontSize(), FONT_SIZE_VALUE);
199 }
200 
201 /**
202  * @tc.name: SymbolPropertyTest002
203  * @tc.desc: test symbol fontWeight property of symbol
204  * @tc.type: FUNC
205  */
206 HWTEST_F(SymbolTestNg, SymbolPropertyTest002, TestSize.Level1)
207 {
208     /**
209      * @tc.steps: step1. create symbol node
210      */
211     SymbolModelNG symbolModelNG;
212     symbolModelNG.Create(CREATE_VALUE);
213     symbolModelNG.SetFontWeight(FontWeight::W100);
214 
215     /**
216      * @tc.steps: step2. get symbol node and layoutProperty
217      */
218     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
219     ASSERT_NE(frameNode, nullptr);
220     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
221     ASSERT_NE(layoutProperty, nullptr);
222     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
223     ASSERT_NE(textLayoutProperty, nullptr);
224 
225     /**
226      * @tc.steps: step3. test get fontWeight property
227      */
228     const std::unique_ptr<FontStyle>& symbolStyle = textLayoutProperty->GetFontStyle();
229     ASSERT_NE(symbolStyle, nullptr);
230     EXPECT_EQ(symbolStyle->GetFontWeight(), FontWeight::W100);
231 }
232 
233 /**
234  * @tc.name: SymbolPropertyTest003
235  * @tc.desc: test symbol renderStrategy property of symbol
236  * @tc.type: FUNC
237  */
238 HWTEST_F(SymbolTestNg, SymbolPropertyTest003, TestSize.Level1)
239 {
240     /**
241      * @tc.steps: step1. create symbol node
242      */
243     SymbolModelNG symbolModelNG;
244     symbolModelNG.Create(CREATE_VALUE);
245     symbolModelNG.SetSymbolRenderingStrategy(RENDER_STRATEGY);
246 
247     /**
248      * @tc.steps: step2. get symbol node and layoutProperty
249      */
250     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
251     ASSERT_NE(frameNode, nullptr);
252     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
253     ASSERT_NE(layoutProperty, nullptr);
254     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
255     ASSERT_NE(textLayoutProperty, nullptr);
256 
257     /**
258      * @tc.steps: step3. test get renderStrategy property
259      */
260     const std::unique_ptr<FontStyle>& symbolStyle = textLayoutProperty->GetFontStyle();
261     ASSERT_NE(symbolStyle, nullptr);
262     auto textStyle = CreateTextStyleUsingTheme(symbolStyle, nullptr, nullptr);
263     EXPECT_EQ(textStyle.GetRenderStrategy(), RENDER_STRATEGY);
264 }
265 
266 /**
267  * @tc.name: SymbolPropertyTest004
268  * @tc.desc: test symbol color property of symbol
269  * @tc.type: FUNC
270  */
271 HWTEST_F(SymbolTestNg, SymbolPropertyTest004, TestSize.Level1)
272 {
273     /**
274      * @tc.steps: step1. create symbol node
275      */
276     SymbolModelNG symbolModelNG;
277     symbolModelNG.Create(CREATE_VALUE);
278     symbolModelNG.SetFontColor(SYMBOL_COLOR_LIST);
279 
280     /**
281      * @tc.steps: step2. get symbol node and layoutProperty
282      */
283     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
284     ASSERT_NE(frameNode, nullptr);
285     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
286     ASSERT_NE(layoutProperty, nullptr);
287     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
288     ASSERT_NE(textLayoutProperty, nullptr);
289 
290     /**
291      * @tc.steps: step3. test get color property
292      */
293     const std::unique_ptr<FontStyle>& symbolStyle = textLayoutProperty->GetFontStyle();
294     ASSERT_NE(symbolStyle, nullptr);
295     auto textStyle = CreateTextStyleUsingTheme(symbolStyle, nullptr, nullptr);
296     EXPECT_EQ(textStyle.GetRenderColors(), SYMBOL_COLOR_LIST);
297 }
298 
299 /**
300  * @tc.name: SymbolPropertyTest005
301  * @tc.desc: test symbol effectStrategy property of symbol
302  * @tc.type: FUNC
303  */
304 HWTEST_F(SymbolTestNg, SymbolPropertyTest005, TestSize.Level1)
305 {
306     /**
307      * @tc.steps: step1. create symbol node
308      */
309     SymbolModelNG symbolModelNG;
310     symbolModelNG.Create(CREATE_VALUE);
311     symbolModelNG.SetSymbolEffect(EFFECT_STRATEGY);
312 
313     /**
314      * @tc.steps: step2. get symbol node and layoutProperty
315      */
316     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
317     ASSERT_NE(frameNode, nullptr);
318 
319     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
320     ASSERT_NE(layoutProperty, nullptr);
321     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
322     ASSERT_NE(textLayoutProperty, nullptr);
323 
324     /**
325      * @tc.steps: step3. test get effectStrategy property
326      */
327     const std::unique_ptr<FontStyle>& symbolStyle = textLayoutProperty->GetFontStyle();
328     ASSERT_NE(symbolStyle, nullptr);
329     auto textStyle = CreateTextStyleUsingTheme(symbolStyle, nullptr, nullptr);
330     EXPECT_EQ(textStyle.GetEffectStrategy(), EFFECT_STRATEGY);
331 }
332 
333 /**
334  * @tc.name: SymbolPropertyTest006
335  * @tc.desc: test symbol symbolEffect property of symbol
336  * @tc.type: FUNC
337  */
338 HWTEST_F(SymbolTestNg, SymbolPropertyTest006, TestSize.Level1)
339 {
340     /**
341      * @tc.steps: step1. create symbol node
342      */
343     SymbolModelNG symbolModelNG;
344     symbolModelNG.Create(CREATE_VALUE);
345     symbolModelNG.SetSymbolEffectOptions(SYMBOL_EFFECT_OPTIONS);
346 
347     /**
348      * @tc.steps: step2. get symbol node and layoutProperty
349      */
350     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
351     ASSERT_NE(frameNode, nullptr);
352 
353     RefPtr<LayoutProperty> layoutProperty = frameNode->GetLayoutProperty();
354     ASSERT_NE(layoutProperty, nullptr);
355     RefPtr<TextLayoutProperty> textLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(layoutProperty);
356     ASSERT_NE(textLayoutProperty, nullptr);
357 
358     /**
359      * @tc.steps: step3. test get symbolEffect property
360      */
361     const std::unique_ptr<FontStyle>& symbolStyle = textLayoutProperty->GetFontStyle();
362     ASSERT_NE(symbolStyle, nullptr);
363     auto textStyle = CreateTextStyleUsingTheme(symbolStyle, nullptr, nullptr);
364     auto symbolOptions = textStyle.GetSymbolEffectOptions().value_or(SymbolEffectOptions());
365     EXPECT_EQ(symbolOptions.GetEffectType(), OHOS::Ace::SymbolEffectType::BOUNCE);
366     EXPECT_EQ(symbolOptions.GetScopeType(), OHOS::Ace::ScopeType::WHOLE);
367     EXPECT_EQ(symbolOptions.GetCommonSubType(), OHOS::Ace::CommonSubType::UP);
368 }
369 
370 /**
371  * @tc.name: SymbolPropertyTest007
372  * @tc.desc: test static method of symbol model
373  * @tc.type: FUNC
374  */
375 HWTEST_F(SymbolTestNg, SymbolPropertyTest007, TestSize.Level1)
376 {
377     MockPipelineContext::SetUp();
378     auto frameNode = SymbolModelNG::CreateFrameNode(CREATE_VALUE);
379     ASSERT_NE(frameNode, nullptr);
380     auto node = AceType::RawPtr(frameNode);
381     ASSERT_NE(node, nullptr);
382 
383     SymbolModelNG::SetFontColor(node, SYMBOL_COLOR_LIST);
384     SymbolModelNG::SetFontSize(node, FONT_SIZE_VALUE);
385     SymbolModelNG::SetFontWeight(node, FontWeight::W100);
386     SymbolModelNG::SetRenderingStrategy(node, RENDER_STRATEGY);
387     SymbolModelNG::SetSymbolEffect(node, EFFECT_STRATEGY);
388     SymbolModelNG::SetSymbolEffectOptions(node, SYMBOL_EFFECT_OPTIONS);
389 
390     RefPtr<LayoutProperty> property = frameNode->GetLayoutProperty();
391     ASSERT_NE(property, nullptr);
392 
393     RefPtr<TextLayoutProperty> textProperty = AceType::DynamicCast<TextLayoutProperty>(property);
394     ASSERT_NE(textProperty, nullptr);
395     const std::unique_ptr<FontStyle>& symbolStyle = textProperty->GetFontStyle();
396     ASSERT_NE(symbolStyle, nullptr);
397 
398     auto textStyle = CreateTextStyleUsingTheme(symbolStyle, nullptr, nullptr);
399     auto effectOptions = textStyle.GetSymbolEffectOptions().value_or(SymbolEffectOptions());
400     EXPECT_EQ(textStyle.GetRenderColors(), SYMBOL_COLOR_LIST);
401     EXPECT_EQ(textStyle.GetFontSize(), FONT_SIZE_VALUE);
402     EXPECT_EQ(symbolStyle->GetFontWeight(), FontWeight::W100);
403     EXPECT_EQ(textStyle.GetEffectStrategy(), EFFECT_STRATEGY);
404     EXPECT_EQ(effectOptions.GetEffectType(), OHOS::Ace::SymbolEffectType::BOUNCE);
405     EXPECT_EQ(effectOptions.GetScopeType(), OHOS::Ace::ScopeType::WHOLE);
406     EXPECT_EQ(effectOptions.GetCommonSubType(), OHOS::Ace::CommonSubType::UP);
407 }
408 } // namespace OHOS::Ace::NG