1 /*
2  * Copyright (c) 2023 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 "test/unittest/core/pattern/rich_editor/rich_editor_common_test_ng.h"
16 
17 using namespace testing;
18 using namespace testing::ext;
19 
20 namespace OHOS::Ace::NG {
21 
22 class RichEditorBaseTestOneNg : public RichEditorCommonTestNg {
23 public:
24     void SetUp() override;
25     void TearDown() override;
26     static void TearDownTestSuite();
27 };
28 
SetUp()29 void RichEditorBaseTestOneNg::SetUp()
30 {
31     MockPipelineContext::SetUp();
32     MockContainer::SetUp();
33     MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
34     auto* stack = ViewStackProcessor::GetInstance();
35     auto nodeId = stack->ClaimNodeId();
36     richEditorNode_ = FrameNode::GetOrCreateFrameNode(
37         V2::RICH_EDITOR_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<RichEditorPattern>(); });
38     ASSERT_NE(richEditorNode_, nullptr);
39     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
40     richEditorPattern->InitScrollablePattern();
41     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
42     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
43     richEditorPattern->CreateNodePaintMethod();
44     richEditorNode_->GetGeometryNode()->SetContentSize({});
45 }
46 
TearDown()47 void RichEditorBaseTestOneNg::TearDown()
48 {
49     richEditorNode_ = nullptr;
50     MockParagraph::TearDown();
51 }
52 
TearDownTestSuite()53 void RichEditorBaseTestOneNg::TearDownTestSuite()
54 {
55     TestNG::TearDownTestSuite();
56 }
57 
58 /**
59  * @tc.name: RichEditorController015
60  * @tc.desc: test use span & imagespan & symbolspan together
61  * @tc.type: FUNC
62  */
63 HWTEST_F(RichEditorBaseTestOneNg, RichEditorController015, TestSize.Level1)
64 {
65     /**
66      * @tc.steps: step1. get richEditor controller
67      */
68     ASSERT_NE(richEditorNode_, nullptr);
69     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
70     ASSERT_NE(richEditorPattern, nullptr);
71     auto richEditorController = richEditorPattern->GetRichEditorController();
72     ASSERT_NE(richEditorController, nullptr);
73 
74     /**
75      * @tc.steps: step2. initalize span properties
76      */
77     SymbolSpanOptions options1;
78     options1.symbolId = SYMBOL_ID;
79     TextSpanOptions options2;
80     options2.value = INIT_VALUE_1;
81     ImageSpanOptions options3;
82     options3.image = IMAGE_VALUE;
83 
84     /**
85      * @tc.steps: step3. test add span
86      */
87     richEditorController->AddSymbolSpan(options1);
88     richEditorController->AddTextSpan(options2);
89     richEditorController->AddImageSpan(options3);
90     richEditorController->AddTextSpan(options2);
91     richEditorController->AddSymbolSpan(options1);
92     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 5);
93 
94     /**
95      * @tc.steps: step4. test get span
96      */
97     auto info1 = richEditorController->GetSpansInfo(0, 3);
98     EXPECT_EQ(info1.selection_.resultObjects.size(), 2);
99     auto info2 = richEditorController->GetSpansInfo(8, 9);
100     EXPECT_EQ(info2.selection_.resultObjects.size(), 1);
101 
102     /**
103      * @tc.steps: step5. test update span
104      */
105     TextStyle textStyle;
106     textStyle.SetFontSize(FONT_SIZE_VALUE_2);
107     struct UpdateSpanStyle updateSpanStyle;
108     updateSpanStyle.updateFontSize = FONT_SIZE_VALUE_2;
109     richEditorController->SetUpdateSpanStyle(updateSpanStyle);
110     ImageSpanAttribute imageStyle;
111     richEditorController->UpdateSpanStyle(2, 8, textStyle, imageStyle);
112 
113     auto newSpan2 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(1));
114     ASSERT_NE(newSpan2, nullptr);
115     EXPECT_EQ(newSpan2->GetFontSize(), FONT_SIZE_VALUE_2);
116 
117     /**
118      * @tc.steps: step6. test delete span
119      */
120     RangeOptions option;
121     option.start = 8;
122     option.end = 15;
123     richEditorController->DeleteSpans(option);
124     EXPECT_EQ(richEditorNode_->GetChildren().size(), 3);
125 
126     option.start = 0;
127     option.end = 2;
128     richEditorController->DeleteSpans(option);
129     EXPECT_EQ(richEditorNode_->GetChildren().size(), 2);
130 
131     ClearSpan();
132 }
133 
134 /**
135  * @tc.name: RichEditorController016
136  * @tc.desc: test add many spans
137  * @tc.type: FUNC
138  */
139 HWTEST_F(RichEditorBaseTestOneNg, RichEditorController016, TestSize.Level1)
140 {
141     /**
142      * @tc.steps: step1. get richEditor controller
143      */
144     ASSERT_NE(richEditorNode_, nullptr);
145     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
146     ASSERT_NE(richEditorPattern, nullptr);
147     auto richEditorController = richEditorPattern->GetRichEditorController();
148     ASSERT_NE(richEditorController, nullptr);
149 
150     /**
151      * @tc.steps: step2. initalize span properties
152      */
153     SymbolSpanOptions options1;
154     options1.symbolId = SYMBOL_ID;
155     TextSpanOptions options2;
156     options2.value = INIT_VALUE_1;
157     ImageSpanOptions options3;
158     options3.image = IMAGE_VALUE;
159 
160     /**
161      * @tc.steps: step3. test add span
162      */
163     for (int i = 0; i < 100; i++) {
164         richEditorController->AddSymbolSpan(options1);
165         richEditorController->AddTextSpan(options2);
166         richEditorController->AddImageSpan(options3);
167         richEditorController->AddTextSpan(options2);
168         richEditorController->AddSymbolSpan(options1);
169     }
170     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 500);
171 
172     ClearSpan();
173 }
174 
175 /**
176  * @tc.name: SetEnterKeyType
177  * @tc.desc: test SetEnterKeyType
178  * @tc.type: FUNC
179  */
180 HWTEST_F(RichEditorBaseTestOneNg, SetEnterKeyType, TestSize.Level1)
181 {
182     /**
183      * @tc.steps: step1. get richEditor controller
184      */
185     ASSERT_NE(richEditorNode_, nullptr);
186     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
187     ASSERT_NE(richEditorPattern, nullptr);
188 
189     RichEditorModelNG richEditorModel;
190     richEditorModel.Create();
191     richEditorModel.SetEnterKeyType(TextInputAction::NEW_LINE);
192     richEditorNode_->MarkModifyDone();
193     EXPECT_EQ(richEditorPattern->GetTextInputActionValue(richEditorPattern->GetDefaultTextInputAction()),
194         TextInputAction::NEW_LINE);
195     richEditorModel.SetEnterKeyType(TextInputAction::UNSPECIFIED);
196     richEditorNode_->MarkModifyDone();
197     EXPECT_EQ(richEditorPattern->GetTextInputActionValue(richEditorPattern->GetDefaultTextInputAction()),
198         TextInputAction::NEW_LINE);
199     ClearSpan();
200 }
201 
202 /**
203  * @tc.name: SupportAvoidanceTest
204  * @tc.desc: test whether the custom keyboard supports the collision avoidance function
205  * @tc.type: FUNC
206  */
207 HWTEST_F(RichEditorBaseTestOneNg, SupportAvoidanceTest, TestSize.Level1)
208 {
209     auto pipeline = PipelineContext::GetCurrentContext();
210     auto overlayManager = pipeline->GetOverlayManager();
211     ASSERT_NE(richEditorNode_, nullptr);
212     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
213     auto supportAvoidance = true;
214     richEditorPattern->SetCustomKeyboardOption(supportAvoidance);
215     auto support = richEditorPattern->keyboardAvoidance_;
216     overlayManager->SetCustomKeyboardOption(support);
217     EXPECT_TRUE(richEditorPattern->keyboardAvoidance_);
218     supportAvoidance = false;
219     richEditorPattern->SetCustomKeyboardOption(supportAvoidance);
220     overlayManager->SetCustomKeyboardOption(support);
221     EXPECT_FALSE(richEditorPattern->keyboardAvoidance_);
222 }
223 
224 /**
225  * @tc.name: IsSelectAreaVisible001
226  * @tc.desc: test selectArea inVisible
227  * @tc.type: FUNC
228  */
229 HWTEST_F(RichEditorBaseTestOneNg, IsSelectAreaVisible001, TestSize.Level1)
230 {
231     ASSERT_NE(richEditorNode_, nullptr);
232     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
233     ASSERT_NE(richEditorPattern, nullptr);
234     /**
235      * @tc.steps: step1. add text and paragraph
236      */
237     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
238     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
239     AddParagraph(paragraphItem);
240     richEditorPattern->textSelector_.baseOffset = 0;
241     richEditorPattern->textSelector_.destinationOffset = 6;
242     richEditorPattern->contentRect_ = { 0.0, 0.0, 500.0, 500.0 };
243     /**
244      * @tc.steps: step2. test IsSelectAreaVisible
245      */
246     auto res = richEditorPattern->IsSelectAreaVisible();
247     EXPECT_FALSE(res);
248 }
249 
250 /**
251  * @tc.name: IsSelectAreaVisible002
252  * @tc.desc: test selectArea Visible
253  * @tc.type: FUNC
254  */
255 HWTEST_F(RichEditorBaseTestOneNg, IsSelectAreaVisible002, TestSize.Level1)
256 {
257     ASSERT_NE(richEditorNode_, nullptr);
258     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
259     ASSERT_NE(richEditorPattern, nullptr);
260     /**
261      * @tc.steps: step1. add text and paragraph
262      */
263     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { -400.0, -400.0, 200.0, 200.0 } } };
264     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
265     AddParagraph(paragraphItem);
266     richEditorPattern->textSelector_.baseOffset = 0;
267     richEditorPattern->textSelector_.destinationOffset = 6;
268     richEditorPattern->contentRect_ = { -500.0, -500.0, 500.0, 500.0 };
269     /**
270      * @tc.steps: step2. test IsSelectAreaVisible
271      */
272     auto res = richEditorPattern->IsSelectAreaVisible();
273     EXPECT_TRUE(res);
274 }
275 
276 /**
277  * @tc.name: onDraw001
278  * @tc.desc: Verify the onDraw Magnifier.
279  * @tc.type: FUNC
280  */
281 HWTEST_F(RichEditorBaseTestOneNg, onDraw001, TestSize.Level1)
282 {
283     Offset localOffset(0, 0);
284     SymbolSpanOptions symbolSpanOptions;
285     symbolSpanOptions.symbolId = SYMBOL_ID;
286 
287     //Verify the selected single line text magnifying glass
288     OnDrawVerify(SelectSpanType::TYPESPAN, INIT_VALUE_1, symbolSpanOptions, localOffset, true);
289 
290     //Verify the selected multi line text magnifying glass
291     OnDrawVerify(SelectSpanType::TYPESPAN, INIT_VALUE_3, symbolSpanOptions, localOffset, true);
292 
293     //Verify the selected image magnifying glass
294     OnDrawVerify(SelectSpanType::TYPEIMAGE, INIT_VALUE_1, symbolSpanOptions, localOffset, true);
295 
296     //Verify the selected symbol magnifying glass
297     OnDrawVerify(SelectSpanType::TYPESYMBOLSPAN, INIT_VALUE_1, symbolSpanOptions, localOffset, true);
298 
299     //Verify insertion status with a regular text magnifying glass
300     OnDrawVerify(SelectSpanType::TYPESPAN, INIT_VALUE_1, symbolSpanOptions, localOffset);
301 
302     //Verify the insertion status of the image magnifying glass
303     OnDrawVerify(SelectSpanType::TYPEIMAGE, INIT_VALUE_1, symbolSpanOptions, localOffset);
304 
305     //Verify the insertion state symbol magnifying glass
306     OnDrawVerify(SelectSpanType::TYPESYMBOLSPAN, INIT_VALUE_1, symbolSpanOptions, localOffset);
307 }
308 
309 /**
310  * @tc.name: RichEditorController017
311  * @tc.desc: test update span style
312  * @tc.type: FUNC
313  */
314 HWTEST_F(RichEditorBaseTestOneNg, RichEditorController017, TestSize.Level1)
315 {
316     /**
317      * @tc.steps: step1. get richEditor controller
318      */
319     ASSERT_NE(richEditorNode_, nullptr);
320     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
321     ASSERT_NE(richEditorPattern, nullptr);
322     auto richEditorController = richEditorPattern->GetRichEditorController();
323     ASSERT_NE(richEditorController, nullptr);
324 
325     /**
326      * @tc.steps: step2. test add span
327      */
328     AddSpan(INIT_VALUE_1);
329     AddImageSpan();
330     AddSpan(INIT_VALUE_2);
331     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 3);
332 
333     /**
334      * @tc.steps: step3. test update span
335      */
336     TextStyle textStyle;
337     textStyle.SetFontSize(FONT_SIZE_VALUE);
338     TextStyle textStyle2;
339     textStyle2.SetFontSize(FONT_SIZE_VALUE_2);
340     struct UpdateSpanStyle updateSpanStyle;
341     updateSpanStyle.updateFontSize = FONT_SIZE_VALUE_2;
342     richEditorController->SetUpdateSpanStyle(updateSpanStyle);
343     ImageSpanAttribute imageStyle;
344 
345     /**
346      * @tc.cases: case. call UpdateSpanStyle(), cover branch end < 0
347      * @tc.expected: expect GetFontSize() is equal to FONT_SIZE_VALUE
348      */
349     richEditorController->UpdateSpanStyle(0, -1, textStyle, imageStyle);
350     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
351     ASSERT_NE(newSpan1, nullptr);
352     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE);
353 
354     /**
355      * @tc.cases: case. call UpdateSpanStyle(), update FontSize to FONT_SIZE_VALUE_2, cover branch end > length
356      * @tc.expected: expect GetFontSize() is equal to FONT_SIZE_VALUE_2
357      */
358     richEditorController->UpdateSpanStyle(0, 20, textStyle2, imageStyle);
359     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE_2);
360 
361     /**
362      * @tc.cases: case. call UpdateSpanStyle(), update FontSize to FONT_SIZE_VALUE, cover branch start > end
363      * @tc.expected: expect GetFontSize() is equal to FONT_SIZE_VALUE
364      */
365     richEditorController->UpdateSpanStyle(10, 0, textStyle, imageStyle);
366     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE);
367 
368     /**
369      * @tc.cases: case. call UpdateSpanStyle(), update FontSize to FONT_SIZE_VALUE_2, cover branch start == end
370      * @tc.expected: expect GetFontSize() is still equal to FONT_SIZE_VALUE
371      */
372     richEditorController->UpdateSpanStyle(0, 0, textStyle2, imageStyle);
373     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE);
374 
375     /**
376      * @tc.cases: case. call UpdateSpanStyle(), update FontSize to FONT_SIZE_VALUE_2, cover branch start > length
377      * @tc.expected: expect GetFontSize() is still equal to FONT_SIZE_VALUE
378      */
379     richEditorController->UpdateSpanStyle(20, 30, textStyle2, imageStyle);
380     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE);
381     ClearSpan();
382 }
383 
384 /**
385  * @tc.name: RichEditorEventHub001
386  * @tc.desc: test get insert
387  * @tc.type: FUNC
388  */
389 HWTEST_F(RichEditorBaseTestOneNg, RichEditorEventHub001, TestSize.Level1)
390 {
391     /**
392      * @tc.steps: step1. set insert value
393      */
394     RichEditorInsertValue insertValueInfo;
395     insertValueInfo.SetInsertOffset(1);
396     insertValueInfo.SetInsertValue(INIT_VALUE_1);
397     /**
398      * @tc.steps: step2. get insert value
399      */
400     EXPECT_EQ(insertValueInfo.GetInsertOffset(), 1);
401     EXPECT_EQ(insertValueInfo.GetInsertValue(), INIT_VALUE_1);
402 }
403 
404 /**
405  * @tc.name: RichEditorEventHub002
406  * @tc.desc: test span result
407  * @tc.type: FUNC
408  */
409 HWTEST_F(RichEditorBaseTestOneNg, RichEditorEventHub002, TestSize.Level1)
410 {
411     /**
412      * @tc.steps: step1. set span result
413      */
414     RichEditorAbstractSpanResult result;
415     FONT_FEATURES_LIST fontFeature;
416     RefPtr<ResourceObject> valueResource;
417     SymbolSpanStyle symbolSpanStyle;
418 
419     result.SetSpanRangeEnd(1);
420     result.SetFontFeature(fontFeature);
421     result.SetLineHeight(20.0);
422     result.SetLetterspacing(20.0);
423     result.SetValueResource(valueResource);
424     result.SetValueString(INIT_VALUE_1);
425     result.SetSymbolSpanStyle(symbolSpanStyle);
426     result.SetTextDecoration(TextDecoration::UNDERLINE);
427     result.SetColor("");
428 
429     /**
430      * @tc.steps: step2. get span result
431      */
432     EXPECT_EQ(result.GetSpanRangeEnd(), 1);
433     EXPECT_EQ(result.GetFontFeatures(), fontFeature);
434     EXPECT_EQ(result.GetLineHeight(), 20.0);
435     EXPECT_EQ(result.GetLetterspacing(), 20.0);
436     EXPECT_EQ(result.GetFontColor(), "");
437     EXPECT_EQ(result.GetFontSize(), 0);
438     EXPECT_EQ(result.GetValueResource(), valueResource);
439     EXPECT_EQ(result.GetValueString(), INIT_VALUE_1);
440     EXPECT_EQ(result.GetSymbolSpanStyle().lineHeight, 0.0);
441     EXPECT_EQ(result.GetFontWeight(), 0);
442     EXPECT_EQ(result.GetFontFamily(), "");
443     EXPECT_EQ(result.GetTextDecoration(), TextDecoration::UNDERLINE);
444     EXPECT_EQ(result.GetColor(), "");
445 }
446 
447 /**
448  * @tc.name: RichEditorEventHub003
449  * @tc.desc: test edit change event
450  * @tc.type: FUNC
451  */
452 HWTEST_F(RichEditorBaseTestOneNg, RichEditorEventHub003, TestSize.Level1)
453 {
454     /**
455      * @tc.steps: step1. set OnEditingChange func
456      */
457     RichEditorModelNG richEditorModel;
458     richEditorModel.Create();
__anonbc5a96c90202(bool value) 459     auto func = [](bool value) {
460         g_isOnEditChangeCalled = value;
461     };
462     richEditorModel.SetOnEditingChange(std::move(func));
463 
464     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
465     ASSERT_NE(richEditorNode, nullptr);
466     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
467     ASSERT_NE(richEditorPattern, nullptr);
468     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
469     ASSERT_NE(eventHub, nullptr);
470 
471     /**
472      * @tc.steps: step2. fire OnEditingChange func
473      * @tc.expected: expect g_isOnEditChangeCalled is true
474      */
475     eventHub->FireOnEditingChange(true);
476     EXPECT_EQ(g_isOnEditChangeCalled, true);
477 
478     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
479         ViewStackProcessor::GetInstance()->elementsStack_.pop();
480     }
481 }
482 
483 /**
484  * @tc.name: RichEditorEventHub004
485  * @tc.desc: test GetDragExtraParams
486  * @tc.type: FUNC
487  */
488 HWTEST_F(RichEditorBaseTestOneNg, RichEditorEventHub004, TestSize.Level1)
489 {
490     ASSERT_NE(richEditorNode_, nullptr);
491     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
492     ASSERT_NE(richEditorPattern, nullptr);
493     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
494     ASSERT_NE(eventHub, nullptr);
495     /**
496      * @tc.cases: case. call GetDragExtraParams(), cover branch !extraInfo.empty()
497      * @tc.expected: expect return jsonStr is {"extraInfo":"info"}
498      */
499     auto jsonStr = eventHub->GetDragExtraParams("info", Point(0, 250.f), DragEventType::MOVE);
500     EXPECT_EQ(jsonStr, "{\"extraInfo\":\"info\"}");
501 
502     /**
503      * @tc.cases: case. call GetDragExtraParams(), cover branch type == DragEventType::DROP
504      * @tc.expected: expect return jsonStr is {"extraInfo":"info"}
505      */
506     jsonStr = eventHub->GetDragExtraParams("info", Point(0, 250.f), DragEventType::DROP);
507     EXPECT_EQ(jsonStr, "{\"extraInfo\":\"info\"}");
508 
509     /**
510      * @tc.cases: case. call GetDragExtraParams(), cover branch timestamp_ != 0
511      * @tc.expected: expect return jsonStr is {}
512      */
513     auto timestamp = std::chrono::system_clock::now().time_since_epoch().count();
514     eventHub->timestamp_ = timestamp;
515     jsonStr = eventHub->GetDragExtraParams("", Point(0, 250.f), DragEventType::DROP);
516     EXPECT_EQ(jsonStr, "{}");
517 
518     /**
519      * @tc.cases: case. call GetDragExtraParams(), cover branch pattern->GetTimestamp() == timestamp_
520      * @tc.expected: expect return jsonStr is {"isInComponent":true}
521      */
522     richEditorPattern->timestamp_ = timestamp;
523     jsonStr = eventHub->GetDragExtraParams("", Point(0, 250.f), DragEventType::DROP);
524     EXPECT_EQ(jsonStr, "{\"isInComponent\":true}");
525     EXPECT_EQ(eventHub->timestamp_, 0);
526 }
527 
528 /**
529  * @tc.name: RichEditorEventHub005
530  * @tc.desc: test fire event
531  * @tc.type: FUNC
532  */
533 HWTEST_F(RichEditorBaseTestOneNg, RichEditorEventHub005, TestSize.Level1)
534 {
535     /**
536      * @tc.steps: step1. init eventHub
537      */
538     RichEditorModelNG richEditorModel;
539     richEditorModel.Create();
540     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
541     ASSERT_NE(richEditorNode_, nullptr);
542     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
543     ASSERT_NE(richEditorPattern, nullptr);
544     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
545     ASSERT_NE(eventHub, nullptr);
546 
547     /**
548      * @tc.steps: step2. fire event when there is null func
549      */
550     RichEditorChangeValue value;
551     StyledStringChangeValue info;
552     TextCommonEvent event;
553     eventHub->FireOnDidChange(value);
554     eventHub->FireOnCut(event);
555     eventHub->FireOnCopy(event);
556     EXPECT_TRUE(eventHub->FireOnWillChange(value));
557     EXPECT_TRUE(eventHub->FireOnStyledStringWillChange(info));
558 
559     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
560         ViewStackProcessor::GetInstance()->elementsStack_.pop();
561     }
562 }
563 
564 /**
565  * @tc.name: ParagraphManager001
566  * @tc.desc: Test the paragraph manager GetHeight function.
567  * @tc.type: FUNC
568  */
569 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager001, TestSize.Level1)
570 {
571     ASSERT_NE(richEditorNode_, nullptr);
572     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
573     /**
574      * @tc.steps: step1. test to obtain initial height
575      */
576     auto height = richEditorPattern->paragraphs_.GetHeight();
577     EXPECT_EQ(height, 0.0f);
578 
579     /**
580      * @tc.steps: step2. add paragraph
581      */
582     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
583     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
584     AddParagraph(paragraphItem);
585 
586     /**
587      * @tc.steps: step3. test get height
588      */
589     height = richEditorPattern->paragraphs_.GetHeight();
590     EXPECT_EQ(height, 0.0f);
591 }
592 
593 /**
594  * @tc.name: ParagraphManager002
595  * @tc.desc: Test the paragraph manager GetMaxIntrinsicWidth function.
596  * @tc.type: FUNC
597  */
598 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager002, TestSize.Level1)
599 {
600     ASSERT_NE(richEditorNode_, nullptr);
601     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
602     /**
603      * @tc.steps: step1. test to obtain initial max intrinsic width
604      */
605     double maxIntrinsicWidth = richEditorPattern->paragraphs_.GetMaxIntrinsicWidth();
606     EXPECT_EQ(maxIntrinsicWidth, 0.0f);
607 
608     /**
609      * @tc.steps: step2. add paragraph
610      */
611     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
612     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
613     AddParagraph(paragraphItem);
614 
615     /**
616      * @tc.steps: step3. test get maxIntrinsicWidth
617      */
618     maxIntrinsicWidth = richEditorPattern->paragraphs_.GetMaxIntrinsicWidth();
619     EXPECT_EQ(maxIntrinsicWidth, 0.0f);
620 }
621 
622 /**
623  * @tc.name: ParagraphManager003
624  * @tc.desc: Test the paragraph manager DidExceedMaxLines function.
625  * @tc.type: FUNC
626  */
627 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager003, TestSize.Level1)
628 {
629     ASSERT_NE(richEditorNode_, nullptr);
630     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
631     /**
632      * @tc.steps: step1. test to obtain initial exceed max lines
633      */
634     bool didExceedMaxLines = richEditorPattern->paragraphs_.DidExceedMaxLines();
635     EXPECT_EQ(didExceedMaxLines, false);
636 
637     /**
638      * @tc.steps: step2. add paragraph
639      */
640     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
641     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
642     AddParagraph(paragraphItem);
643 
644     /**
645      * @tc.steps: step3. test didExceedMaxLines
646      */
647     didExceedMaxLines = richEditorPattern->paragraphs_.DidExceedMaxLines();
648     EXPECT_EQ(didExceedMaxLines, false);
649 }
650 
651 /**
652  * @tc.name: ParagraphManager004
653  * @tc.desc: Test the paragraph manager GetLongestLine function.
654  * @tc.type: FUNC
655  */
656 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager004, TestSize.Level1)
657 {
658     ASSERT_NE(richEditorNode_, nullptr);
659     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
660     /**
661      * @tc.steps: step1. test to obtain initial max intrinsic width
662      */
663     double longestLine = richEditorPattern->paragraphs_.GetLongestLine();
664     EXPECT_EQ(longestLine, 0.0f);
665 
666     /**
667      * @tc.steps: step2. add paragraph
668      */
669     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
670     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
671     AddParagraph(paragraphItem);
672 
673     /**
674      * @tc.steps: step3. test get longest line
675      */
676     longestLine = richEditorPattern->paragraphs_.GetLongestLine();
677     EXPECT_EQ(longestLine, 0.0f);
678 }
679 
680 /**
681  * @tc.name: ParagraphManager005
682  * @tc.desc: Test the paragraph manager GetMaxWidth function.
683  * @tc.type: FUNC
684  */
685 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager005, TestSize.Level1)
686 {
687     ASSERT_NE(richEditorNode_, nullptr);
688     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
689     /**
690      * @tc.steps: step1. test to obtain initial max width
691      */
692     double maxWidth = richEditorPattern->paragraphs_.GetMaxWidth();
693     EXPECT_EQ(maxWidth, 0.0f);
694 
695     /**
696      * @tc.steps: step2. add paragraph
697      */
698     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
699     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
700     AddParagraph(paragraphItem);
701 
702     /**
703      * @tc.steps: step3. test get max width
704      */
705     maxWidth = richEditorPattern->paragraphs_.GetMaxWidth();
706     EXPECT_EQ(maxWidth, 0.0f);
707 }
708 
709 /**
710  * @tc.name: ParagraphManager006
711  * @tc.desc: Test the paragraph manager GetTextWidth function.
712  * @tc.type: FUNC
713  */
714 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager006, TestSize.Level1)
715 {
716     ASSERT_NE(richEditorNode_, nullptr);
717     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
718     /**
719      * @tc.steps: step1. test to obtain initial max width
720      */
721     double maxTextWidth = richEditorPattern->paragraphs_.GetTextWidth();
722     EXPECT_EQ(maxTextWidth, 0.0f);
723 
724     /**
725      * @tc.steps: step2. add paragraph
726      */
727     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
728     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
729     AddParagraph(paragraphItem);
730 
731     /**
732      * @tc.steps: step3. test get text width
733      */
734     maxTextWidth = richEditorPattern->paragraphs_.GetTextWidth();
735     EXPECT_EQ(maxTextWidth, 0.0f);
736 }
737 
738 /**
739  * @tc.name: ParagraphManager007
740  * @tc.desc: Test the paragraph manager GetTextWidthIncludeIndent function.
741  * @tc.type: FUNC
742  */
743 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager007, TestSize.Level1)
744 {
745     ASSERT_NE(richEditorNode_, nullptr);
746     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
747     /**
748      * @tc.steps: step1. test to obtain initial text width include indent
749      */
750     double textWidthIncludeIndent = richEditorPattern->paragraphs_.GetTextWidthIncludeIndent();
751     EXPECT_EQ(textWidthIncludeIndent, 0.0f);
752 
753     /**
754      * @tc.steps: step2. add paragraph
755      */
756     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
757     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
758     AddParagraph(paragraphItem);
759 
760     /**
761      * @tc.steps: step3. test get text width include indent
762      */
763     textWidthIncludeIndent = richEditorPattern->paragraphs_.GetTextWidthIncludeIndent();
764     EXPECT_EQ(textWidthIncludeIndent, 0.0f);
765 }
766 
767 /**
768  * @tc.name: ParagraphManager008
769  * @tc.desc: Test the paragraph manager GetLineCount function.
770  * @tc.type: FUNC
771  */
772 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager008, TestSize.Level1)
773 {
774     ASSERT_NE(richEditorNode_, nullptr);
775     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
776     /**
777      * @tc.steps: step1. test to obtain initial line count
778      */
779     size_t dineCount = richEditorPattern->paragraphs_.GetLineCount();
780     EXPECT_EQ(dineCount, 0);
781 
782     /**
783      * @tc.steps: step2. add paragraph
784      */
785     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
786     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
787     AddParagraph(paragraphItem);
788 
789     /**
790      * @tc.steps: step3. test get line count
791      */
792     dineCount = richEditorPattern->paragraphs_.GetLineCount();
793     EXPECT_EQ(dineCount, 0);
794 }
795 
796 /**
797  * @tc.name: ParagraphManager009
798  * @tc.desc: Test the paragraph manager function.
799  * @tc.type: FUNC
800  */
801 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager009, TestSize.Level1)
802 {
803     ASSERT_NE(richEditorNode_, nullptr);
804     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
805     ASSERT_NE(richEditorPattern, nullptr);
806     /**
807      * @tc.steps: step1. add paragraph
808      */
809     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
810     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
811     AddParagraph(paragraphItem);
812 
813     /**
814      * @tc.steps: step2. test get index
815      */
816     auto textRect = richEditorPattern->GetTextRect();
817     textRect.SetTop(textRect.GetY() - 0.0f);
818     textRect.SetHeight(textRect.Height() - 0.0f);
819     Offset offset = Offset(textRect.GetX(), textRect.GetY());
820     bool clamp = false;
821     int32_t paragraphsIndex = richEditorPattern->paragraphs_.GetIndex(offset, clamp);
822     EXPECT_EQ(paragraphsIndex, 0);
823 
824     /**
825      * @tc.steps: step3. test get glyph index
826      */
827     int32_t glyphIndex = richEditorPattern->paragraphs_.GetGlyphIndexByCoordinate(offset, clamp);
828     EXPECT_EQ(glyphIndex, 0);
829 
830     /**
831      * @tc.steps: step4. test get word boundary
832      */
833     int32_t offset1 = 0;
834     int32_t start = 0;
835     int32_t end = 0;
836     bool wordBoundary = richEditorPattern->paragraphs_.GetWordBoundary(offset1, start, end);
837     EXPECT_EQ(wordBoundary, false);
838 
839     /**
840      * @tc.steps: step5. test calc caret metrics
841      */
842     int32_t extent = 0;
843     CaretMetricsF caretCaretMetric;
844     TextAffinity textAffinity = TextAffinity::DOWNSTREAM;
845     bool caretMetrics = richEditorPattern->paragraphs_.CalcCaretMetricsByPosition(extent, caretCaretMetric,
846         textAffinity);
847     EXPECT_EQ(caretMetrics, false);
848 }
849 
850 /**
851  * @tc.name: ParagraphManager010
852  * @tc.desc: Test the paragraph manager function.
853  * @tc.type: FUNC
854  */
855 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager010, TestSize.Level1)
856 {
857     ASSERT_NE(richEditorNode_, nullptr);
858     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
859     ASSERT_NE(richEditorPattern, nullptr);
860     /**
861      * @tc.steps: step1. add paragraph
862      */
863     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
864     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
865     AddParagraph(paragraphItem);
866 
867     /**
868      * @tc.steps: step2. test get line metrics
869      */
870     RectF rect = { 0.0, 0.0, 100.0, 100.0 };
871     int32_t paragraphIndex = 0;
872     LineMetrics lineMetrics = richEditorPattern->paragraphs_.GetLineMetricsByRectF(rect, paragraphIndex);
873     EXPECT_EQ(lineMetrics.ascender, 0.0f);
874 
875     /**
876      * @tc.steps: step3. test editable status
877      */
878     auto accessibilityProperty = richEditorPattern->CreateAccessibilityProperty();
879     bool isEditable = accessibilityProperty->IsEditable();
880     EXPECT_EQ(isEditable, true);
881 }
882 
883 /**
884  * @tc.name: ParagraphManager011
885  * @tc.desc: Test the paragraph manager function.
886  * @tc.type: FUNC
887  */
888 HWTEST_F(RichEditorBaseTestOneNg, ParagraphManager011, TestSize.Level1)
889 {
890     ASSERT_NE(richEditorNode_, nullptr);
891     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
892     ASSERT_NE(richEditorPattern, nullptr);
893 
894     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
895     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
896     AddParagraph(paragraphItem);
897 
898     bool clamp = true;
899     int32_t paragraphsIndex = richEditorPattern->paragraphs_.GetIndex(Offset(-1.0, -1.0), clamp);
900     EXPECT_EQ(paragraphsIndex, 0);
901 
902     PositionWithAffinity finalResult = richEditorPattern->paragraphs_.GetGlyphPositionAtCoordinate(Offset(-1.0, -1.0));
903     EXPECT_EQ(finalResult.position_, 0);
904 }
905 
906 /**
907  * @tc.name: Controller001
908  * @tc.desc: Test the controller function.
909  * @tc.type: FUNC
910  */
911 HWTEST_F(RichEditorBaseTestOneNg, Controller001, TestSize.Level1)
912 {
913     ASSERT_NE(richEditorNode_, nullptr);
914     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
915     ASSERT_NE(richEditorPattern, nullptr);
916     /**
917      * @tc.steps: step1. add paragraph
918      */
919     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
920     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
921     AddParagraph(paragraphItem);
922 
923     TextStyle style;
924     style.SetLineHeight(LINE_HEIGHT_VALUE);
925     style.SetLetterSpacing(LETTER_SPACING);
926     style.SetFontFeatures(TEXT_FONTFEATURE);
927     TextSpanOptions options;
928     options.value = INIT_VALUE_1;
929     options.style = style;
930     auto richEditorController = richEditorPattern->GetRichEditorController();
931     ASSERT_NE(richEditorController, nullptr);
932     richEditorController->AddTextSpan(options);
933     AddSpan(INIT_VALUE_1);
934     auto info = richEditorController->GetSpansInfo(1, 5);
935     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
936     UpdateSpanStyle typingStyle;
937     richEditorController->SetTypingStyle(typingStyle, style);
938     TextSpanOptions options1;
939     options1.style = richEditorPattern->typingTextStyle_;
940     AddSpan(INIT_VALUE_1);
941     auto info1 = richEditorController->GetSpansInfo(1, 5);
942     TextStyleResult textStyle2 = info1.selection_.resultObjects.front().textStyle;
943     EXPECT_EQ(textStyle2.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
944     EXPECT_EQ(textStyle2.letterSpacing, LETTER_SPACING.ConvertToVp());
945     for (const auto& pair : textStyle1.fontFeature) {
946         EXPECT_EQ(pair.first, "subs");
947         EXPECT_EQ(pair.second, 1);
948     }
949     ClearSpan();
950 }
951 
952 /**
953  * @tc.name: Controller002
954  * @tc.desc: Test the controller function.
955  * @tc.type: FUNC
956  */
957 HWTEST_F(RichEditorBaseTestOneNg, Controller002, TestSize.Level1)
958 {
959     ASSERT_NE(richEditorNode_, nullptr);
960     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
961     ASSERT_NE(richEditorPattern, nullptr);
962     auto richEditorController = richEditorPattern->GetRichEditorController();
963     ASSERT_NE(richEditorController, nullptr);
964 
965     /**
966      * @tc.steps: step1. add paragraph
967      */
968     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
969     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
970     AddParagraph(paragraphItem);
971 
972     TextStyle style;
973     style.SetLineHeight(LINE_HEIGHT_VALUE);
974     style.SetLetterSpacing(LETTER_SPACING);
975     style.SetFontFeatures(TEXT_FONTFEATURE);
976     TextSpanOptions options;
977     options.value = INIT_VALUE_1;
978     options.style = style;
979     richEditorController->AddTextSpan(options);
980     AddSpan(INIT_VALUE_1);
981     richEditorController->SetSelection(1, 3);
982     auto info1 = richEditorController->GetSpansInfo(1, 2);
983     EXPECT_EQ(info1.selection_.resultObjects.front().textStyle.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
984     EXPECT_EQ(info1.selection_.resultObjects.front().textStyle.letterSpacing, LETTER_SPACING.ConvertToVp());
985     for (const auto& pair : info1.selection_.resultObjects.front().textStyle.fontFeature) {
986         EXPECT_EQ(pair.first, "subs");
987         EXPECT_EQ(pair.second, 1);
988     }
989     ClearSpan();
990     richEditorController->CloseSelectionMenu();
991 }
992 
993 /**
994  * @tc.name: ToStyledString001
995  * @tc.desc: Test spans to styledString.
996  * @tc.type: FUNC
997  */
998 HWTEST_F(RichEditorBaseTestOneNg, ToStyledString001, TestSize.Level1)
999 {
1000     ASSERT_NE(richEditorNode_, nullptr);
1001     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1002     ASSERT_NE(richEditorPattern, nullptr);
1003     auto richEditorController = richEditorPattern->GetRichEditorController();
1004     ASSERT_NE(richEditorController, nullptr);
1005 
1006     /**
1007      * @tc.steps: step1. init spans
1008      */
1009     TextSpanOptions options;
1010     options.value = INIT_VALUE_1;
1011     richEditorController->AddTextSpan(options);
1012     options.value = INIT_VALUE_2;
1013     richEditorController->AddTextSpan(options);
1014 
1015     /**
1016      * @tc.steps: step2. test ToStyledString
1017      */
1018     auto spanString = richEditorPattern->ToStyledString(0, 8);
1019     ASSERT_NE(spanString, nullptr);
1020     EXPECT_EQ(spanString->GetSpanItems().size(), 2);
1021 }
1022 
1023 /**
1024  * @tc.name: AddSpanByPasteData001
1025  * @tc.desc: Test add span by pasteData.
1026  * @tc.type: FUNC
1027  */
1028 HWTEST_F(RichEditorBaseTestOneNg, AddSpanByPasteData001, TestSize.Level1)
1029 {
1030     ASSERT_NE(richEditorNode_, nullptr);
1031     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1032     ASSERT_NE(richEditorPattern, nullptr);
1033     auto richEditorController = richEditorPattern->GetRichEditorController();
1034     ASSERT_NE(richEditorController, nullptr);
1035 
1036     /**
1037      * @tc.steps: step1. init spans
1038     */
1039     ImageSpanOptions imageOptions;
1040     void* voidPtr = static_cast<void*>(new char[0]);
1041     RefPtr<PixelMap> pixelMap = PixelMap::CreatePixelMap(voidPtr);
1042     ASSERT_NE(pixelMap, nullptr);
1043     imageOptions.imagePixelMap = pixelMap;
1044     richEditorPattern->AddImageSpan(imageOptions);
1045 
1046     TextSpanOptions options;
1047     options.value = INIT_VALUE_1;
1048     richEditorController->AddTextSpan(options);
1049 
1050     /**
1051      * @tc.steps: step2. test AddSpanByPasteData001
1052      */
1053     auto spanString = richEditorPattern->ToStyledString(0, 8);
1054     ASSERT_NE(spanString, nullptr);
1055     richEditorPattern->spans_.clear();
1056     richEditorPattern->isSpanStringMode_ = false;
1057     richEditorPattern->AddSpanByPasteData(spanString);
1058     EXPECT_EQ(richEditorPattern->spans_.size(), 2);
1059 }
1060 
1061 /**
1062  * @tc.name: RichEditorLayoutAlgorithm001
1063  * @tc.desc: test MeasureContent
1064  * @tc.type: FUNC
1065  */
1066 HWTEST_F(RichEditorBaseTestOneNg, RichEditorLayoutAlgorithm001, TestSize.Level1)
1067 {
1068     ASSERT_NE(richEditorNode_, nullptr);
1069     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1070     ASSERT_NE(richEditorPattern, nullptr);
1071 
1072     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
1073     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
1074     auto richEditorTheme = AceType::MakeRefPtr<RichEditorTheme>();
1075     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(richEditorTheme));
1076 
1077     LayoutConstraintF parentLayoutConstraint;
1078     parentLayoutConstraint.maxSize = CONTAINER_SIZE;
1079 
1080     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(
1081         richEditorNode_, AceType::MakeRefPtr<GeometryNode>(), richEditorNode_->GetLayoutProperty());
1082     ASSERT_NE(layoutWrapper, nullptr);
1083     auto layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
1084     ASSERT_NE(layoutAlgorithm, nullptr);
1085     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
1086 
1087     parentLayoutConstraint.selfIdealSize.SetHeight(std::nullopt);
1088     parentLayoutConstraint.selfIdealSize.SetWidth(1.0f);
1089 
1090     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1091     ASSERT_NE(paragraph, nullptr);
1092 
1093     auto paragraphManager = AceType::MakeRefPtr<ParagraphManager>();
1094     layoutAlgorithm->paragraphManager_ = paragraphManager;
1095 
1096     AddSpan(INIT_VALUE_1);
1097     layoutAlgorithm->spans_.emplace_back(richEditorPattern->spans_);
1098     layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
1099 
1100     layoutAlgorithm->spans_.clear();
1101     auto size1 = layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
1102     EXPECT_EQ(size1.value().Width(), 1.0f);
1103 
1104     richEditorPattern->presetParagraph_ = paragraph;
1105     auto size2 = layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
1106     EXPECT_EQ(size2.value().Width(), 1.0f);
1107 }
1108 
1109 /**
1110  * @tc.name: RichEditorLayoutAlgorithm002
1111  * @tc.desc: test GetParagraphStyleSpanItem
1112  * @tc.type: FUNC
1113  */
1114 HWTEST_F(RichEditorBaseTestOneNg, RichEditorLayoutAlgorithm002, TestSize.Level1)
1115 {
1116     ASSERT_NE(richEditorNode_, nullptr);
1117     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1118     ASSERT_NE(richEditorPattern, nullptr);
1119 
1120     auto layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
1121     ASSERT_NE(layoutAlgorithm, nullptr);
1122 
1123     std::list<RefPtr<SpanItem>> spanGroup;
1124     spanGroup.clear();
1125     spanGroup.emplace_back(AceType::MakeRefPtr<PlaceholderSpanItem>());
1126     auto span = layoutAlgorithm->GetParagraphStyleSpanItem(spanGroup);
1127     EXPECT_EQ(*spanGroup.begin(), span);
1128 }
1129 
1130 /**
1131  * @tc.name: RichEditorLayoutAlgorithm003
1132  * @tc.desc: test Measure
1133  * @tc.type: FUNC
1134  */
1135 HWTEST_F(RichEditorBaseTestOneNg, RichEditorLayoutAlgorithm003, TestSize.Level1)
1136 {
1137     ASSERT_NE(richEditorNode_, nullptr);
1138     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1139     ASSERT_NE(richEditorPattern, nullptr);
1140 
1141     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(
1142         richEditorNode_, AceType::MakeRefPtr<GeometryNode>(), richEditorNode_->GetLayoutProperty());
1143     ASSERT_NE(layoutWrapper, nullptr);
1144     auto layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
1145     ASSERT_NE(layoutAlgorithm, nullptr);
1146     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
1147 
1148     LayoutConstraintF layoutConstraint;
1149     layoutConstraint.maxSize = SizeF(10.0f, 1000.0f);
1150     layoutConstraint.minSize = CONTAINER_SIZE;
1151     layoutWrapper->GetLayoutProperty()->UpdateLayoutConstraint(layoutConstraint);
1152     layoutAlgorithm->Measure(AceType::RawPtr(layoutWrapper));
1153     EXPECT_EQ(layoutWrapper->GetGeometryNode()->GetFrameSize().Width(), 720.0f);
1154 }
1155 
1156 /**
1157  * @tc.name: RichEditorLayoutAlgorithm004
1158  * @tc.desc: test RichEditorLayoutAlgorithm
1159  * @tc.type: FUNC
1160  */
1161 HWTEST_F(RichEditorBaseTestOneNg, RichEditorLayoutAlgorithm004, TestSize.Level1)
1162 {
1163     std::list<RefPtr<SpanItem>> spans;
1164     auto paragraphManager = AceType::MakeRefPtr<ParagraphManager>();
1165     auto placeholderSpanItem = AceType::MakeRefPtr<PlaceholderSpanItem>();
1166     auto spanItem = AceType::MakeRefPtr<SpanItem>();
1167     ASSERT_NE(spanItem, nullptr);
1168 
1169     std::string str = "\n";
1170     spanItem->content = str;
1171     spans.emplace_back(spanItem);
1172     auto layoutAlgorithm = AceType::MakeRefPtr<RichEditorLayoutAlgorithm>(spans, AceType::RawPtr(paragraphManager),
1173         std::nullopt);
1174     ASSERT_NE(layoutAlgorithm, nullptr);
1175     EXPECT_NE(*(layoutAlgorithm->allSpans_.begin()), nullptr);
1176 }
1177 
1178 /**
1179  * @tc.name: IsSelectLineHeadAndUseLeadingMargin001
1180  * @tc.desc: Test the paragraph manager IsSelectLineHeadAndUseLeadingMargin function.
1181  * @tc.type: FUNC
1182  */
1183 HWTEST_F(RichEditorBaseTestOneNg, IsSelectLineHeadAndUseLeadingMargin001, TestSize.Level1)
1184 {
1185     ASSERT_NE(richEditorNode_, nullptr);
1186     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1187     ASSERT_NE(richEditorPattern, nullptr);
1188     auto richEditorController = richEditorPattern->GetRichEditorController();
1189     ASSERT_NE(richEditorController, nullptr);
1190 
1191     /**
1192      * @tc.steps: step1. add paragraph and Mock func.
1193      */
1194     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1195     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1196     AddParagraph(paragraphItem);
1197 
1198     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1199     ASSERT_NE(paragraph, nullptr);
1200     ParagraphStyle testStyle = {};
1201     EXPECT_CALL(*paragraph, GetParagraphStyle())
1202         .WillRepeatedly(ReturnRef(testStyle));
1203     /**
1204      * @tc.steps: step2. test IsSelectLineHeadAndUseLeadingMargin fun
1205     */
1206     bool bRet = richEditorPattern->paragraphs_.IsSelectLineHeadAndUseLeadingMargin(paragraphItem.start);
1207     EXPECT_EQ(bRet, false);
1208 }
1209 
1210 /**
1211  * @tc.name: IsSelectLineHeadAndUseLeadingMargin002
1212  * @tc.desc: Test the paragraph manager IsSelectLineHeadAndUseLeadingMargin function.
1213  * @tc.type: FUNC
1214  */
1215 HWTEST_F(RichEditorBaseTestOneNg, IsSelectLineHeadAndUseLeadingMargin002, TestSize.Level1)
1216 {
1217     ASSERT_NE(richEditorNode_, nullptr);
1218     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1219     ASSERT_NE(richEditorPattern, nullptr);
1220     auto richEditorController = richEditorPattern->GetRichEditorController();
1221     ASSERT_NE(richEditorController, nullptr);
1222 
1223     /**
1224      * @tc.steps: step1. add paragraph and Mock func.
1225      */
1226     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1227     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1228     AddParagraph(paragraphItem);
1229 
1230     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 200.0, 200.0, 400.0, 400.0 } } };
1231     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRectSec } };
1232     AddParagraph(paragraphItemSec);
1233 
1234     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1235     ASSERT_NE(paragraph, nullptr);
1236     ParagraphStyle testStyle = {};
1237     testStyle.leadingMargin = LeadingMargin();
1238     EXPECT_CALL(*paragraph, GetParagraphStyle())
1239         .WillRepeatedly(ReturnRef(testStyle));
1240     /**
1241      * @tc.steps: step2. test IsSelectLineHeadAndUseLeadingMargin fun
1242     */
1243     int start = richEditorPattern->paragraphs_.paragraphs_.begin()->start;
1244     bool bRet = richEditorPattern->paragraphs_.IsSelectLineHeadAndUseLeadingMargin(start);
1245     EXPECT_EQ(bRet, true);
1246 }
1247 
1248 /**
1249  * @tc.name: IsSelectLineHeadAndUseLeadingMargin003
1250  * @tc.desc: Test the paragraph manager IsSelectLineHeadAndUseLeadingMargin function.
1251  * @tc.type: FUNC
1252  */
1253 HWTEST_F(RichEditorBaseTestOneNg, IsSelectLineHeadAndUseLeadingMargin003, TestSize.Level1)
1254 {
1255     ASSERT_NE(richEditorNode_, nullptr);
1256     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1257     ASSERT_NE(richEditorPattern, nullptr);
1258     auto richEditorController = richEditorPattern->GetRichEditorController();
1259     ASSERT_NE(richEditorController, nullptr);
1260 
1261     /**
1262      * @tc.steps: step1. add paragraph and Mock func.
1263      */
1264     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1265     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1266     AddParagraph(paragraphItem);
1267 
1268     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 200.0, 200.0, 400.0, 400.0 } } };
1269     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRectSec } };
1270     AddParagraph(paragraphItemSec);
1271 
1272     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1273     ASSERT_NE(paragraph, nullptr);
1274     ParagraphStyle testStyle = {};
1275     testStyle.leadingMargin = LeadingMargin();
1276     EXPECT_CALL(*paragraph, GetParagraphStyle())
1277         .WillRepeatedly(ReturnRef(testStyle));
1278     /**
1279      * @tc.steps: step2. test IsSelectLineHeadAndUseLeadingMargin fun
1280     */
1281     bool bRet = richEditorPattern->paragraphs_.IsSelectLineHeadAndUseLeadingMargin(paragraphRect.end);
1282     EXPECT_EQ(bRet, true);
1283 }
1284 
1285 /**
1286  * @tc.name: GetIndex001
1287  * @tc.desc: Test the paragraph manager function.
1288  * @tc.type: FUNC
1289  */
1290 HWTEST_F(RichEditorBaseTestOneNg, GetGetIndex001, TestSize.Level1)
1291 {
1292     ASSERT_NE(richEditorNode_, nullptr);
1293     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1294     ASSERT_NE(richEditorPattern, nullptr);
1295 
1296     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1297     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1298     AddParagraph(paragraphItem);
1299     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1300     ASSERT_NE(paragraph, nullptr);
1301     EXPECT_CALL(*paragraph, GetHeight()).WillRepeatedly(Return(800.0f));
1302     EXPECT_CALL(*paragraph, GetGlyphIndexByCoordinate(_, _)).WillRepeatedly(Return(6));
1303     PositionWithAffinity positionWithAffinity(2, TextAffinity::UPSTREAM);
1304     EXPECT_CALL(*paragraph, GetGlyphPositionAtCoordinate(_)).WillRepeatedly(Return(positionWithAffinity));
1305 
1306     bool clamp = true;
1307     int32_t paragraphsIndex = richEditorPattern->paragraphs_.GetIndex(Offset(100.0, -10.0), clamp);
1308     EXPECT_EQ(paragraphsIndex, 0);
1309     paragraphsIndex = richEditorPattern->paragraphs_.GetIndex(Offset(100.0, 0.0), clamp);
1310     EXPECT_EQ(paragraphsIndex, 6);
1311     clamp = false;
1312     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 200.0, 200.0, 600.0, 600.0 } } };
1313     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRectSec } };
1314     AddParagraph(paragraphItemSec);
1315     paragraphsIndex = richEditorPattern->paragraphs_.GetIndex(Offset(100.0, 900.0), clamp);
1316     EXPECT_EQ(paragraphsIndex, 13);
1317 }
1318 
1319 /**
1320  * @tc.name: GetGlyphPositionAtCoordinate001
1321  * @tc.desc: Test the paragraph manager function.
1322  * @tc.type: FUNC
1323  */
1324 HWTEST_F(RichEditorBaseTestOneNg, GetGlyphPositionAtCoordinate001, TestSize.Level1)
1325 {
1326     ASSERT_NE(richEditorNode_, nullptr);
1327     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1328     ASSERT_NE(richEditorPattern, nullptr);
1329 
1330     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1331     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1332     AddParagraph(paragraphItem);
1333     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1334     ASSERT_NE(paragraph, nullptr);
1335     EXPECT_CALL(*paragraph, GetHeight()).WillRepeatedly(Return(800.0f));
1336     EXPECT_CALL(*paragraph, GetGlyphIndexByCoordinate(_, _)).WillRepeatedly(Return(6));
1337     PositionWithAffinity positionWithAffinity(2, TextAffinity::UPSTREAM);
1338     EXPECT_CALL(*paragraph, GetGlyphPositionAtCoordinate(_)).WillRepeatedly(Return(positionWithAffinity));
1339     bool clamp = false;
1340     int32_t paragraphsIndex = richEditorPattern->paragraphs_.GetIndex(Offset(100.0, 0.0), clamp);
1341     EXPECT_EQ(paragraphsIndex, 6);
1342 
1343     PositionWithAffinity finalResult = richEditorPattern->paragraphs_.GetGlyphPositionAtCoordinate(Offset(0.0, 0.0));
1344     EXPECT_EQ(finalResult.position_, 2);
1345     finalResult = richEditorPattern->paragraphs_.GetGlyphPositionAtCoordinate(Offset(0.0, -10.0));
1346     EXPECT_EQ(finalResult.position_, 0);
1347     finalResult = richEditorPattern->paragraphs_.GetGlyphPositionAtCoordinate(Offset(0.0, 900.0));
1348     EXPECT_EQ(finalResult.position_, 2);
1349 }
1350 
1351 /**
1352  * @tc.name: GetLineMetrics001
1353  * @tc.desc: Test the paragraph manager function.
1354  * @tc.type: FUNC
1355  */
1356 HWTEST_F(RichEditorBaseTestOneNg, GetLineMetrics001, TestSize.Level1)
1357 {
1358     ASSERT_NE(richEditorNode_, nullptr);
1359     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1360     ASSERT_NE(richEditorPattern, nullptr);
1361 
1362     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1363     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1364     AddParagraph(paragraphItem);
1365     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1366     ASSERT_NE(paragraph, nullptr);
1367     EXPECT_CALL(*paragraph, GetLineCount()).WillRepeatedly(Return(1));
1368     TextLineMetrics textLineMetrics;
1369     textLineMetrics.lineNumber = 0;
1370     EXPECT_CALL(*paragraph, GetLineMetrics(_)).WillRepeatedly(Return(textLineMetrics));
1371 
1372     TextLineMetrics finalResult = richEditorPattern->paragraphs_.GetLineMetrics(0);
1373     EXPECT_EQ(finalResult.lineNumber, 0);
1374 
1375     finalResult = richEditorPattern->paragraphs_.GetLineMetrics(2);
1376     EXPECT_EQ(finalResult.lineNumber, 0);
1377 
1378     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 200.0, 200.0, 600.0, 600.0 } } };
1379     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRectSec } };
1380     AddParagraph(paragraphItemSec);
1381     finalResult = richEditorPattern->paragraphs_.GetLineMetrics(1);
1382     EXPECT_EQ(finalResult.lineNumber, 1);
1383 }
1384 
1385 /**
1386  * @tc.name: GetGlyphIndexByCoordinate001
1387  * @tc.desc: Test the paragraph manager function.
1388  * @tc.type: FUNC
1389  */
1390 HWTEST_F(RichEditorBaseTestOneNg, GetGlyphIndexByCoordinate001, TestSize.Level1)
1391 {
1392     ASSERT_NE(richEditorNode_, nullptr);
1393     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1394     ASSERT_NE(richEditorPattern, nullptr);
1395     /**
1396      * @tc.steps: step1. add paragraph
1397      */
1398     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1399     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1400     AddParagraph(paragraphItem);
1401     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1402     ASSERT_NE(paragraph, nullptr);
1403     EXPECT_CALL(*paragraph, GetHeight()).WillRepeatedly(Return(800.0f));
1404     /**
1405      * @tc.steps: step2. test get glyph index
1406      */
1407     int32_t glyphIndex = richEditorPattern->paragraphs_.GetGlyphIndexByCoordinate(Offset(0.0, 1000.00), true);
1408     EXPECT_EQ(glyphIndex, 6);
1409 }
1410 
1411 /**
1412  * @tc.name: GetWordBoundary001
1413  * @tc.desc: Test the paragraph manager function.
1414  * @tc.type: FUNC
1415  */
1416 HWTEST_F(RichEditorBaseTestOneNg, GetWordBoundary001, TestSize.Level1)
1417 {
1418     ASSERT_NE(richEditorNode_, nullptr);
1419     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1420     ASSERT_NE(richEditorPattern, nullptr);
1421     /**
1422      * @tc.steps: step1. add paragraph
1423      */
1424     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1425     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1426     AddParagraph(paragraphItem);
1427 
1428     /**
1429      * @tc.steps: step2. test get glyph index
1430      */
1431     int32_t glyphIndex = richEditorPattern->paragraphs_.GetWordBoundary(1000, paragraphItem.start, paragraphItem.end);
1432     EXPECT_EQ(glyphIndex, 0);
1433 }
1434 
1435 /**
1436  * @tc.name: GetLineMetricsByRectF001
1437  * @tc.desc: Test the paragraph manager function.
1438  * @tc.type: FUNC
1439  */
1440 HWTEST_F(RichEditorBaseTestOneNg, GetLineMetricsByRectF001, TestSize.Level1)
1441 {
1442     ASSERT_NE(richEditorNode_, nullptr);
1443     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1444     ASSERT_NE(richEditorPattern, nullptr);
1445     /**
1446      * @tc.steps: step1. add paragraph
1447      */
1448     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1449     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1450     AddParagraph(paragraphItem);
1451 
1452     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 200.0, 200.0, 400.0, 400.0 } } };
1453     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRect } };
1454     AddParagraph(paragraphItemSec);
1455     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1456     ASSERT_NE(paragraph, nullptr);
1457     EXPECT_CALL(*paragraph, GetHeight()).WillRepeatedly(Return(800.0f));
1458 
1459     /**
1460      * @tc.steps: step2. test get glyph index
1461      */
1462     LineMetrics testMetrics = richEditorPattern->paragraphs_.GetLineMetricsByRectF(RectF(0.0, 100.0, 200.0, 300.0), 1);
1463     EXPECT_EQ(testMetrics.y, 800);
1464 }
1465 
1466 /**
1467  * @tc.name: CalcCaretMetricsByPosition001
1468  * @tc.desc: Test the paragraph manager function.
1469  * @tc.type: FUNC
1470  */
1471 HWTEST_F(RichEditorBaseTestOneNg, CalcCaretMetricsByPosition001, TestSize.Level1)
1472 {
1473     ASSERT_NE(richEditorNode_, nullptr);
1474     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1475     ASSERT_NE(richEditorPattern, nullptr);
1476     /**
1477      * @tc.steps: step1. add paragraph
1478      */
1479     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
1480     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1481     AddParagraph(paragraphItem);
1482 
1483     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 200.0, 200.0, 400.0, 400.0 } } };
1484     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRectSec } };
1485     AddParagraph(paragraphItemSec);
1486 
1487     TestParagraphRect paragraphRectThr = { .start = 13, .end = 20, .rects = { { 200.0, 200.0, 400.0, 400.0 } } };
1488     TestParagraphItem paragraphItemThr = { .start = 13, .end = 20, .testParagraphRects = { paragraphRectThr } };
1489     AddParagraph(paragraphItemThr);
1490     /**
1491      * @tc.steps: step5. test calc caret metrics
1492      */
1493     int32_t extent = 0;
1494     CaretMetricsF caretCaretMetric;
1495     TextAffinity textAffinity = TextAffinity::DOWNSTREAM;
1496     bool caretMetrics = richEditorPattern->paragraphs_.CalcCaretMetricsByPosition(extent, caretCaretMetric,
1497         textAffinity);
1498     EXPECT_EQ(caretMetrics, false);
1499 }
1500 } // namespace OHOS::Ace::NG
1501