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 <optional>
16 #include <vector>
17 
18 #include "gtest/gtest.h"
19 
20 #define private public
21 #define protected public
22 
23 #include "test/mock/base/mock_task_executor.h"
24 #include "test/mock/core/common/mock_container.h"
25 #include "test/mock/core/common/mock_theme_manager.h"
26 #include "test/mock/core/pipeline/mock_pipeline_context.h"
27 #include "test/mock/core/render/mock_paragraph.h"
28 #include "test/mock/core/render/mock_render_context.h"
29 #include "test/mock/core/rosen/mock_canvas.h"
30 
31 #include "base/geometry/dimension.h"
32 #include "base/geometry/ng/offset_t.h"
33 #include "base/image/pixel_map.h"
34 #include "base/memory/ace_type.h"
35 #include "base/memory/referenced.h"
36 #include "base/utils/string_utils.h"
37 #include "base/window/drag_window.h"
38 #include "core/components/common/layout/constants.h"
39 #include "core/components/common/properties/text_style.h"
40 #include "core/components_ng/base/frame_node.h"
41 #include "core/components_ng/base/geometry_node.h"
42 #include "core/components_ng/base/view_abstract_model.h"
43 #include "core/components_ng/base/view_stack_processor.h"
44 #include "core/components_ng/layout/layout_property.h"
45 #include "core/components_ng/pattern/image/image_pattern.h"
46 #include "core/components_ng/pattern/overlay/keyboard_view.h"
47 #include "core/components_ng/pattern/pattern.h"
48 #include "core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.h"
49 #include "core/components_ng/pattern/rich_editor/rich_editor_model.h"
50 #include "core/components_ng/pattern/rich_editor/rich_editor_model_ng.h"
51 #include "core/components_ng/pattern/rich_editor/rich_editor_overlay_modifier.h"
52 #include "core/components_ng/pattern/rich_editor/rich_editor_pattern.h"
53 #include "core/components_ng/pattern/rich_editor/rich_editor_theme.h"
54 #include "core/components_ng/pattern/rich_editor/selection_info.h"
55 #include "core/components_ng/pattern/root/root_pattern.h"
56 #include "core/components_ng/pattern/select_overlay/select_overlay_property.h"
57 #include "core/components_ng/pattern/text/span_model_ng.h"
58 #include "core/components_ng/pattern/text/span_node.h"
59 #include "core/components_ng/pattern/text_field/text_field_manager.h"
60 #include "core/components_ng/pattern/text_field/text_selector.h"
61 #include "core/components_ng/render/paragraph.h"
62 #include "test/mock/core/render/mock_render_context.h"
63 #include "test/mock/core/rosen/mock_canvas.h"
64 #include "test/mock/core/common/mock_theme_manager.h"
65 #include "test/mock/core/common/mock_data_detector_mgr.h"
66 #include "core/components_v2/inspector/inspector_constants.h"
67 #include "core/event/key_event.h"
68 #include "core/event/mouse_event.h"
69 #include "core/event/touch_event.h"
70 #include "core/pipeline/base/constants.h"
71 #include "test/unittest/core/pattern/test_ng.h"
72 
73 using namespace testing;
74 using namespace testing::ext;
75 
76 namespace OHOS::Ace::NG {
77 namespace {
78 int32_t testOnReadyEvent = 0;
79 int32_t testAboutToIMEInput = 0;
80 int32_t testOnIMEInputComplete = 0;
81 int32_t testAboutToDelete = 0;
82 int32_t testOnDeleteComplete = 0;
83 int32_t testOnSelect = 0;
84 SelectionRangeInfo testSelectionRange(0, 0);
85 int32_t callBack1 = 0;
86 int32_t callBack2 = 0;
87 int32_t callBack3 = 0;
88 const std::string INIT_VALUE_1 = "hello1";
89 const std::string INIT_VALUE_2 = "hello2";
90 const std::string INIT_VALUE_3 = "hello world! hello world! hello world!";
91 const std::string TEST_INSERT_VALUE = "s";
92 const std::string TEST_INSERT_LINE_SEP = "\n";
93 const std::string EXCEPT_VALUE = "h\n";
94 const Dimension FONT_SIZE_VALUE = Dimension(20.1, DimensionUnit::PX);
95 const Dimension FONT_SIZE_VALUE_2 = Dimension(40, DimensionUnit::PX);
96 const Color TEXT_COLOR_VALUE = Color::FromRGB(255, 100, 100);
97 const Ace::FontStyle ITALIC_FONT_STYLE_VALUE = Ace::FontStyle::ITALIC;
98 const Ace::FontWeight FONT_WEIGHT_VALUE = Ace::FontWeight::W100;
99 const Ace::FontWeight FONT_WEIGHT_BOLD = Ace::FontWeight::BOLD;
100 const std::vector<std::string> FONT_FAMILY_VALUE = { "cursive" };
101 const Ace::TextDecoration TEXT_DECORATION_VALUE = Ace::TextDecoration::INHERIT;
102 const Color TEXT_DECORATION_COLOR_VALUE = Color::FromRGB(255, 100, 100);
103 const Ace::TextCase TEXT_CASE_VALUE = Ace::TextCase::LOWERCASE;
104 const Dimension LETTER_SPACING = Dimension(10, DimensionUnit::PX);
105 const Dimension LINE_HEIGHT_VALUE = Dimension(20.1, DimensionUnit::PX);
106 const Shadow TEXT_SHADOW1 = Shadow(0, 0, Offset(), Color::RED);
107 const Shadow TEXT_SHADOW2 = Shadow(0, 0, Offset(), Color::WHITE);
108 const std::vector<Shadow> SHADOWS { TEXT_SHADOW1, TEXT_SHADOW2 };
109 const std::string IMAGE_VALUE = "image1";
110 const std::string BUNDLE_NAME = "bundleName";
111 const std::string MODULE_NAME = "moduleName";
112 const std::string PREVIEW_TEXT_VALUE1 = "nihao";
113 const std::string PREVIEW_TEXT_VALUE2 = "nihaodajia";
114 const std::string PREVIEW_TEXT_VALUE3 = "dajia";
115 const std::string ROOT_TAG = "root";
116 const CalcLength CALC_LENGTH_CALC { 10.0, DimensionUnit::CALC };
117 const CalcLength ERROR_CALC_LENGTH_CALC { -10.0, DimensionUnit::CALC };
118 const Dimension CALC_TEST { 10.0, DimensionUnit::CALC };
119 const Dimension ERROR_CALC_TEST { -10.0, DimensionUnit::CALC };
120 const Offset MOUSE_GLOBAL_LOCATION = { 100, 200 };
121 const uint32_t SYMBOL_ID = 1;
122 std::list<std::pair<std::string, int32_t>> TEXT_FONTFEATURE = {{ "subs", 1 }};
123 std::list<std::pair<std::string, int32_t>> TEXT_FONTFEATURE_2 = {{ "subs", 0 }};
124 std::vector<Color> SYMBOL_COLOR_LIST_1 = { Color::FromRGB(255, 100, 100) };
125 std::vector<Color> SYMBOL_COLOR_LIST_2 = { Color::FromRGB(255, 100, 100), Color::FromRGB(255, 255, 100) };
126 const uint32_t RENDER_STRATEGY_SINGLE = 0;
127 const uint32_t RENDER_STRATEGY_MULTI_COLOR = 1;
128 const uint32_t EFFECT_STRATEGY_NONE = 0;
129 const uint32_t EFFECT_STRATEGY_SCALE = 1;
130 constexpr int32_t WORD_LIMIT_LEN = 6;
131 constexpr int32_t WORD_LIMIT_RETURN = 2;
132 constexpr int32_t BEYOND_LIMIT_RETURN = 4;
133 constexpr int32_t DEFAULT_RETURN_VALUE = -1;
134 constexpr int32_t THIRD_PARAM = 2;
135 const SizeF CONTAINER_SIZE(720.0f, 1136.0f);
136 constexpr float DEFAILT_OPACITY = 0.2f;
137 constexpr Color SYSTEM_CARET_COLOR = Color(0xff007dff);
138 constexpr Color SYSTEM_SELECT_BACKGROUND_COLOR = Color(0x33007dff);
139 constexpr float CONTEXT_WIDTH_VALUE = 300.0f;
140 constexpr float CONTEXT_HEIGHT_VALUE = 150.0f;
141 const Color DEFAULT_TEXT_COLOR_VALUE = Color::FromARGB(229, 0, 0, 0);
142 bool g_isOnWillChangeCalled = false;
143 bool g_isOnDidChangeCalled = false;
144 RichEditorChangeValue onWillChangeValue;
145 RichEditorChangeValue onDidChangeValue;
146 auto& onWillRangeBefore = onWillChangeValue.rangeBefore_;
147 auto& onWillReplacedSpans = onWillChangeValue.replacedSpans_;
148 auto& onWillReplacedImageSpans = onWillChangeValue.replacedImageSpans_;
149 auto& onWillReplacedSymbolSpans = onWillChangeValue.replacedSymbolSpans_;
150 auto& onDidRangeBefore = onDidChangeValue.rangeBefore_;
151 auto& onDidRangeAfter = onDidChangeValue.rangeAfter_;
152 const TextStyle TEXT_STYLE_1(10.0);
153 const TextStyle TEXT_STYLE_2(20.0);
154 const TextStyle TEXT_STYLE_3(30.0);
155 const TextSpanOptions TEXT_SPAN_OPTIONS_1 = { .value = INIT_VALUE_1, .style = TEXT_STYLE_1 };
156 const ImageSpanAttribute IMAGE_SPAN_ATTRIBUTE_1 = {
157     .size = ImageSpanSize{ .width = 200.0_px, .height = 100.0_px },
158     .verticalAlign = VerticalAlign::CENTER,
159     .objectFit = ImageFit::COVER,
160     .marginProp = std::nullopt,
161     .borderRadius = std::nullopt,
162     .paddingProp = std::nullopt
163 };
164 const ImageSpanOptions IMAGE_SPAN_OPTIONS_1 = {
165     .offset = std::nullopt,
166     .image = "app.media.icon",
167     .bundleName = std::nullopt,
168     .moduleName = std::nullopt,
169     .imagePixelMap = std::nullopt,
170     .imageAttribute = IMAGE_SPAN_ATTRIBUTE_1
171 };
172 
173 struct TestCursorItem {
174     int32_t index;
175     CaretMetricsF caretMetricsFDown;
176     CaretMetricsF caretMetricsFUp;
177 };
178 
179 struct TestParagraphRect {
180     int32_t start;
181     int32_t end;
182     std::vector<RectF> rects;
183 };
184 
185 struct TestParagraphItem {
186     int32_t start;
187     int32_t end;
188     int32_t height;
189     ParagraphStyle paragraphStyle;
190     std::map<int32_t, Offset> indexOffsetMap;
191     std::vector<TestCursorItem> testCursorItems;
192     std::vector<TestParagraphRect> testParagraphRects;
193 };
194 } // namespace
195 
196 class RichEditorTestNg : public TestNG {
197 public:
198     void SetUp() override;
199     void TearDown() override;
200     void AddSpan(const std::string& content);
201     void AddImageSpan();
202     void AddParagraph(TestParagraphItem testParagraphItem);
203     void ClearParagraph();
204     void ClearSpan();
205     void InitAdjustObject(MockDataDetectorMgr& mockDataDetectorMgr);
206     void RequestFocus();
207     void GetFocus(const RefPtr<RichEditorPattern>& pattern);
208     void OnDrawVerify(const SelectSpanType& type, const std::string& text, SymbolSpanOptions options, Offset offset,
209         bool selected = false);
210     void ResetContentChangeCallbackState();
211     void InitContentChangeCallback(RichEditorModelNG& richEditorModel);
212 
213 protected:
MockKeyboardBuilder()214     static void MockKeyboardBuilder() {}
215     RefPtr<FrameNode> richEditorNode_;
216 };
217 
ResetContentChangeCallbackState()218 void RichEditorTestNg::ResetContentChangeCallbackState()
219 {
220     g_isOnWillChangeCalled = false;
221     g_isOnDidChangeCalled = false;
222     onWillChangeValue.reset();
223     onDidChangeValue.reset();
224 }
225 
InitContentChangeCallback(RichEditorModelNG & richEditorModel)226 void RichEditorTestNg::InitContentChangeCallback(RichEditorModelNG& richEditorModel)
227 {
228     ResetContentChangeCallbackState();
229     auto onWillChange = [](const RichEditorChangeValue& changeValue) {
230         g_isOnWillChangeCalled = true;
231         onWillChangeValue = changeValue;
232         return true;
233     };
234     richEditorModel.SetOnWillChange(std::move(onWillChange));
235 
236     auto onDidChange = [](const RichEditorChangeValue& changeValue) {
237         g_isOnDidChangeCalled = true;
238         onDidChangeValue = changeValue;
239     };
240     richEditorModel.SetOnDidChange(std::move(onDidChange));
241 }
242 
SetUp()243 void RichEditorTestNg::SetUp()
244 {
245     MockPipelineContext::SetUp();
246     MockContainer::SetUp();
247     MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
248     auto* stack = ViewStackProcessor::GetInstance();
249     auto nodeId = stack->ClaimNodeId();
250     richEditorNode_ = FrameNode::GetOrCreateFrameNode(
251         V2::RICH_EDITOR_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<RichEditorPattern>(); });
252     ASSERT_NE(richEditorNode_, nullptr);
253     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
254     richEditorPattern->InitScrollablePattern();
255     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
256     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
257     richEditorPattern->CreateNodePaintMethod();
258     richEditorNode_->GetGeometryNode()->SetContentSize({});
259 }
260 
TearDown()261 void RichEditorTestNg::TearDown()
262 {
263     richEditorNode_ = nullptr;
264     testOnReadyEvent = 0;
265     testAboutToIMEInput = 0;
266     testOnIMEInputComplete = 0;
267     testAboutToDelete = 0;
268     testOnDeleteComplete = 0;
269     MockPipelineContext::TearDown();
270     MockParagraph::TearDown();
271 }
272 
AddSpan(const std::string & content)273 void RichEditorTestNg::AddSpan(const std::string& content)
274 {
275     ASSERT_NE(richEditorNode_, nullptr);
276     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
277     ASSERT_NE(richEditorPattern, nullptr);
278     SpanModelNG spanModelNG;
279     spanModelNG.Create(content);
280     spanModelNG.SetFontSize(FONT_SIZE_VALUE);
281     spanModelNG.SetTextColor(TEXT_COLOR_VALUE);
282     spanModelNG.SetItalicFontStyle(ITALIC_FONT_STYLE_VALUE);
283     spanModelNG.SetFontWeight(FONT_WEIGHT_VALUE);
284     spanModelNG.SetFontFamily(FONT_FAMILY_VALUE);
285     spanModelNG.SetTextDecoration(TEXT_DECORATION_VALUE);
286     spanModelNG.SetTextDecorationColor(TEXT_DECORATION_COLOR_VALUE);
287     spanModelNG.SetTextCase(TEXT_CASE_VALUE);
288     spanModelNG.SetLetterSpacing(LETTER_SPACING);
289     spanModelNG.SetLineHeight(LINE_HEIGHT_VALUE);
290     spanModelNG.SetTextShadow(SHADOWS);
291     auto spanNode = AceType::DynamicCast<SpanNode>(ViewStackProcessor::GetInstance()->Finish());
292     spanNode->MountToParent(richEditorNode_, richEditorNode_->children_.size());
293     richEditorPattern->spans_.emplace_back(spanNode->spanItem_);
294     int32_t spanTextLength = 0;
295     for (auto& span : richEditorPattern->spans_) {
296         spanTextLength += StringUtils::ToWstring(span->content).length();
297         span->position = spanTextLength;
298     }
299 }
300 
AddImageSpan()301 void RichEditorTestNg::AddImageSpan()
302 {
303     auto* stack = ViewStackProcessor::GetInstance();
304     auto nodeId = stack->ClaimNodeId();
305     auto imageNode = FrameNode::GetOrCreateFrameNode(
306         V2::IMAGE_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<ImagePattern>(); });
307     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
308     ASSERT_NE(imageLayoutProperty, nullptr);
309     ImageSourceInfo imageInfo(IMAGE_VALUE, BUNDLE_NAME, MODULE_NAME);
310     imageLayoutProperty->UpdateImageSourceInfo(imageInfo);
311     imageNode->MountToParent(richEditorNode_, richEditorNode_->children_.size());
312     auto spanItem = AceType::MakeRefPtr<ImageSpanItem>();
313     spanItem->content = " ";
314     spanItem->placeholderIndex = 0;
315     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
316     ASSERT_NE(richEditorPattern, nullptr);
317     richEditorPattern->spans_.emplace_back(spanItem);
318     int32_t spanTextLength = 0;
319     for (auto& span : richEditorPattern->spans_) {
320         spanTextLength += StringUtils::ToWstring(span->content).length();
321         span->position = spanTextLength;
322     }
323 }
324 
AddParagraph(TestParagraphItem testParagraphItem)325 void RichEditorTestNg::AddParagraph(TestParagraphItem testParagraphItem)
326 {
327     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
328     ASSERT_NE(paragraph, nullptr);
329     ASSERT_NE(richEditorNode_, nullptr);
330     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
331     ASSERT_NE(richEditorPattern, nullptr);
332     richEditorPattern->paragraphs_.AddParagraph(
333         { .paragraph = paragraph, .start = testParagraphItem.start, .end = testParagraphItem.end });
334     for (const auto& [index, offset] : testParagraphItem.indexOffsetMap) {
335         EXPECT_CALL(*paragraph, GetGlyphIndexByCoordinate(offset, false)).WillRepeatedly(Return(index));
336     }
337     for (auto& cursorItem : testParagraphItem.testCursorItems) {
338         EXPECT_CALL(*paragraph, ComputeOffsetForCaretDownstream(cursorItem.index, _, _))
339             .WillRepeatedly(DoAll(SetArgReferee<1>(cursorItem.caretMetricsFDown), Return(true)));
340         EXPECT_CALL(*paragraph, ComputeOffsetForCaretUpstream(cursorItem.index, _, _))
341             .WillRepeatedly(DoAll(SetArgReferee<1>(cursorItem.caretMetricsFUp), Return(true)));
342         float cursorHeight = 0.0f;
343         EXPECT_EQ(richEditorPattern->paragraphs_.ComputeCursorOffset(cursorItem.index, cursorHeight, true),
344             cursorItem.caretMetricsFDown.offset);
345         EXPECT_EQ(richEditorPattern->paragraphs_.ComputeCursorOffset(cursorItem.index, cursorHeight, false),
346             cursorItem.caretMetricsFUp.offset);
347     }
348     for (auto& paragraphRect : testParagraphItem.testParagraphRects) {
349         EXPECT_CALL(*paragraph, GetRectsForRange(paragraphRect.start, paragraphRect.end, _))
350             .WillRepeatedly(SetArgReferee<THIRD_PARAM>(paragraphRect.rects));
351     }
352 }
353 
ClearParagraph()354 void RichEditorTestNg::ClearParagraph()
355 {
356     ASSERT_NE(richEditorNode_, nullptr);
357     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
358     ASSERT_NE(richEditorPattern, nullptr);
359     richEditorPattern->paragraphs_.Reset();
360 }
361 
ClearSpan()362 void RichEditorTestNg::ClearSpan()
363 {
364     ASSERT_NE(richEditorNode_, nullptr);
365     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
366     ASSERT_NE(richEditorPattern, nullptr);
367     richEditorNode_->children_.clear();
368     richEditorPattern->spans_.clear();
369     richEditorPattern->caretPosition_ = 0;
370 }
371 
InitAdjustObject(MockDataDetectorMgr & mockDataDetectorMgr)372 void RichEditorTestNg::InitAdjustObject(MockDataDetectorMgr& mockDataDetectorMgr)
373 {
374     EXPECT_CALL(mockDataDetectorMgr, GetCursorPosition(_, _))
375             .WillRepeatedly([](const std::string &text, int8_t offset) -> int8_t {
376                 if (text.empty()) {
377                     return DEFAULT_RETURN_VALUE;
378                 }
379                 if (text.length() <= WORD_LIMIT_LEN) {
380                     return WORD_LIMIT_RETURN;
381                 } else {
382                     return BEYOND_LIMIT_RETURN;
383                 }
384             });
385 
386     EXPECT_CALL(mockDataDetectorMgr, GetWordSelection(_, _))
387             .WillRepeatedly([](const std::string &text, int8_t offset) -> std::vector<int8_t> {
388                 if (text.empty()) {
389                     return std::vector<int8_t> { -1, -1 };
390                 }
391 
392                 if (text.length() <= WORD_LIMIT_LEN) {
393                     return std::vector<int8_t> { 2, 3 };
394                 } else {
395                     return std::vector<int8_t> { 0, 2 };
396                 }
397             });
398 }
399 
RequestFocus()400 void RichEditorTestNg::RequestFocus()
401 {
402     ASSERT_NE(richEditorNode_, nullptr);
403     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
404     ASSERT_NE(richEditorPattern, nullptr);
405     auto focusHub = richEditorPattern->GetFocusHub();
406     ASSERT_NE(focusHub, nullptr);
407     focusHub->RequestFocusImmediately();
408 }
409 
GetFocus(const RefPtr<RichEditorPattern> & pattern)410 void RichEditorTestNg::GetFocus(const RefPtr<RichEditorPattern>& pattern)
411 {
412     ASSERT_NE(pattern, nullptr);
413     auto focushHub = pattern->GetFocusHub();
414     focushHub->currentFocus_ = true;
415     pattern->HandleFocusEvent();
416     FlushLayoutTask(richEditorNode_);
417 }
418 
OnDrawVerify(const SelectSpanType & type,const std::string & text,SymbolSpanOptions options,Offset offset,bool selected)419 void RichEditorTestNg::OnDrawVerify(
420     const SelectSpanType& type, const std::string& text, SymbolSpanOptions options, Offset offset, bool selected)
421 {
422     /**
423      * @tc.steps: step1. Initialize text input and get focus
424      */
425     ASSERT_NE(richEditorNode_, nullptr);
426     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
427     ASSERT_NE(richEditorPattern, nullptr);
428 
429     if (SelectSpanType::TYPESPAN == type) {
430         AddSpan(text);
431     } else if (SelectSpanType::TYPEIMAGE == type) {
432         AddImageSpan();
433     } else if (SelectSpanType::TYPESYMBOLSPAN == type) {
434         auto richEditorController = richEditorPattern->GetRichEditorController();
435         ASSERT_NE(richEditorController, nullptr);
436         richEditorController->AddSymbolSpan(options);
437     }
438 
439     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
440     GetFocus(richEditorPattern);
441 
442     if (!selected) {
443         GestureEvent info;
444         info.localLocation_ = offset;
445         richEditorPattern->HandleClickEvent(info);
446     } else {
447         richEditorPattern->HandleOnSelectAll();
448     }
449 
450     /**
451      * @tc.steps: step2. Move handle
452      */
453     auto controller = richEditorPattern->GetMagnifierController();
454     ASSERT_NE(controller, nullptr);
455     controller->SetLocalOffset(OffsetF(1.0f, 1.0f));
456     RectF handleRect;
457     richEditorPattern->selectOverlay_->OnHandleMove(handleRect, false);
458 
459     /**
460      * @tc.steps: step3. Test magnifier open or close
461      * @tc.expected: magnifier is open
462      */
463     auto ret = controller->GetShowMagnifier();
464     EXPECT_TRUE(ret);
465 
466     /**
467      * @tc.steps: step4. Craete RichEditorOverlayModifier
468      */
469     EdgeEffect edgeEffect;
470     auto scrollEdgeEffect = AceType::MakeRefPtr<ScrollEdgeEffect>(edgeEffect);
471     auto scrollBarModifier = AceType::MakeRefPtr<ScrollBarOverlayModifier>();
472     auto richFieldOverlayModifier = AceType::MakeRefPtr<RichEditorOverlayModifier>(
473         richEditorPattern, AceType::WeakClaim(AceType::RawPtr(scrollBarModifier)), scrollEdgeEffect);
474     ASSERT_NE(richFieldOverlayModifier, nullptr);
475 
476     /**
477      * @tc.steps: step5. Create DrawingContext
478      */
479     Testing::MockCanvas rsCanvas;
480     EXPECT_CALL(rsCanvas, AttachBrush(_)).WillRepeatedly(ReturnRef(rsCanvas));
481     EXPECT_CALL(rsCanvas, DetachBrush()).WillRepeatedly(ReturnRef(rsCanvas));
482     EXPECT_CALL(rsCanvas, AttachPen(_)).WillRepeatedly(ReturnRef(rsCanvas));
483     EXPECT_CALL(rsCanvas, DetachPen()).WillRepeatedly(ReturnRef(rsCanvas));
484     DrawingContext context { rsCanvas, CONTEXT_WIDTH_VALUE, CONTEXT_HEIGHT_VALUE };
485 
486     /**
487      * @tc.steps: step6. Do onDraw(context)
488      */
489     richFieldOverlayModifier->onDraw(context);
490 
491     /**
492      * @tc.steps: step7. When handle move done
493      */
494     richEditorPattern->selectOverlay_->ProcessOverlay();
495     richEditorPattern->selectOverlay_->OnHandleMoveDone(handleRect, true);
496 
497     /**
498      * @tc.steps: step8. Test magnifier open or close
499      * @tc.expected: magnifier is close
500      */
501     ret = controller->GetShowMagnifier();
502     EXPECT_FALSE(ret);
503 }
504 
505 /**
506  * @tc.name: RichEditorModel001
507  * @tc.desc: test create
508  * @tc.type: FUNC
509  */
510 HWTEST_F(RichEditorTestNg, RichEditorModel001, TestSize.Level1)
511 {
512     ASSERT_NE(richEditorNode_, nullptr);
513     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
514     ASSERT_NE(richEditorPattern, nullptr);
515     RichEditorModelNG richEditorModel;
516     richEditorModel.Create();
517     EXPECT_EQ(ViewStackProcessor::GetInstance()->elementsStack_.size(), 1);
518     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
519         ViewStackProcessor::GetInstance()->elementsStack_.pop();
520     }
521 }
522 
523 /**
524  * @tc.name: RichEditorModel002
525  * @tc.desc: test create
526  * @tc.type: FUNC
527  */
528 HWTEST_F(RichEditorTestNg, RichEditorModel002, TestSize.Level1)
529 {
530     RichEditorModelNG richEditorModel;
531     richEditorModel.Create();
532     richEditorModel.SetDraggable(true);
533     EXPECT_TRUE(ViewStackProcessor::GetInstance()->GetMainFrameNode()->draggable_);
534     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
535         ViewStackProcessor::GetInstance()->elementsStack_.pop();
536     }
537 }
538 
539 /**
540  * @tc.name: RichEditorModel003
541  * @tc.desc: test set on ready
542  * @tc.type: FUNC
543  */
544 HWTEST_F(RichEditorTestNg, RichEditorModel003, TestSize.Level1)
545 {
546     RichEditorModelNG richEditorModel;
547     richEditorModel.Create();
__anon814dfc0d0802() 548     auto func = []() { testOnReadyEvent = 1; };
549     richEditorModel.SetOnReady(std::move(func));
550     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
551     ASSERT_NE(richEditorNode, nullptr);
552     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
553     ASSERT_NE(richEditorPattern, nullptr);
554     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
555     ASSERT_NE(eventHub, nullptr);
556     eventHub->FireOnReady();
557     EXPECT_EQ(testOnReadyEvent, 1);
558     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
559         ViewStackProcessor::GetInstance()->elementsStack_.pop();
560     }
561 }
562 
563 /**
564  * @tc.name: RichEditorModel004
565  * @tc.desc: test set about to IME input
566  * @tc.type: FUNC
567  */
568 HWTEST_F(RichEditorTestNg, RichEditorModel004, TestSize.Level1)
569 {
570     RichEditorModelNG richEditorModel;
571     richEditorModel.Create();
__anon814dfc0d0902(const RichEditorInsertValue&) 572     auto func = [](const RichEditorInsertValue&) {
573         testAboutToIMEInput = 1;
574         return true;
575     };
576     richEditorModel.SetAboutToIMEInput(std::move(func));
577     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
578     ASSERT_NE(richEditorNode, nullptr);
579     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
580     ASSERT_NE(richEditorPattern, nullptr);
581     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
582     ASSERT_NE(eventHub, nullptr);
583     RichEditorInsertValue info;
584     eventHub->FireAboutToIMEInput(info);
585     EXPECT_EQ(testAboutToIMEInput, 1);
586     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
587         ViewStackProcessor::GetInstance()->elementsStack_.pop();
588     }
589 }
590 
591 /**
592  * @tc.name: RichEditorModel005
593  * @tc.desc: test set on IME input complete
594  * @tc.type: FUNC
595  */
596 HWTEST_F(RichEditorTestNg, RichEditorModel005, TestSize.Level1)
597 {
598     RichEditorModelNG richEditorModel;
599     richEditorModel.Create();
__anon814dfc0d0a02(const RichEditorAbstractSpanResult&) 600     auto func = [](const RichEditorAbstractSpanResult&) { testOnIMEInputComplete = 1; };
601     richEditorModel.SetOnIMEInputComplete(std::move(func));
602     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
603     ASSERT_NE(richEditorNode, nullptr);
604     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
605     ASSERT_NE(richEditorPattern, nullptr);
606     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
607     ASSERT_NE(eventHub, nullptr);
608     RichEditorAbstractSpanResult info;
609     eventHub->FireOnIMEInputComplete(info);
610     EXPECT_EQ(testOnIMEInputComplete, 1);
611     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
612         ViewStackProcessor::GetInstance()->elementsStack_.pop();
613     }
614 }
615 
616 /**
617  * @tc.name: RichEditorModel006
618  * @tc.desc: test set about to delete
619  * @tc.type: FUNC
620  */
621 HWTEST_F(RichEditorTestNg, RichEditorModel006, TestSize.Level1)
622 {
623     RichEditorModelNG richEditorModel;
624     richEditorModel.Create();
__anon814dfc0d0b02(const RichEditorDeleteValue&) 625     auto func = [](const RichEditorDeleteValue&) {
626         testAboutToDelete = 1;
627         return true;
628     };
629     richEditorModel.SetAboutToDelete(std::move(func));
630     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
631     ASSERT_NE(richEditorNode, nullptr);
632     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
633     ASSERT_NE(richEditorPattern, nullptr);
634     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
635     ASSERT_NE(eventHub, nullptr);
636     RichEditorDeleteValue info;
637     eventHub->FireAboutToDelete(info);
638     EXPECT_EQ(testAboutToDelete, 1);
639     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
640         ViewStackProcessor::GetInstance()->elementsStack_.pop();
641     }
642 }
643 
644 /**
645  * @tc.name: RichEditorModel007
646  * @tc.desc: test set on delete complete
647  * @tc.type: FUNC
648  */
649 HWTEST_F(RichEditorTestNg, RichEditorModel007, TestSize.Level1)
650 {
651     RichEditorModelNG richEditorModel;
652     richEditorModel.Create();
__anon814dfc0d0c02() 653     auto func = []() { testOnDeleteComplete = 1; };
654     richEditorModel.SetOnDeleteComplete(std::move(func));
655     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
656     ASSERT_NE(richEditorNode, nullptr);
657     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
658     ASSERT_NE(richEditorPattern, nullptr);
659     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
660     ASSERT_NE(eventHub, nullptr);
661     eventHub->FireOnDeleteComplete();
662     EXPECT_EQ(testOnDeleteComplete, 1);
663     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
664         ViewStackProcessor::GetInstance()->elementsStack_.pop();
665     }
666 }
667 
668 /**
669  * @tc.name: RichEditorModel008
670  * @tc.desc: test set on select
671  * @tc.type: FUNC
672  */
673 HWTEST_F(RichEditorTestNg, RichEditorModel008, TestSize.Level1)
674 {
675     RichEditorModelNG richEditorModel;
676     richEditorModel.Create();
__anon814dfc0d0d02(const BaseEventInfo* info) 677     auto func = [](const BaseEventInfo* info) { testOnSelect = 1; };
678     richEditorModel.SetOnSelect(std::move(func));
679     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
680     ASSERT_NE(richEditorNode, nullptr);
681     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
682     ASSERT_NE(richEditorPattern, nullptr);
683     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
684     ASSERT_NE(eventHub, nullptr);
685     SelectionInfo selection;
686     eventHub->FireOnSelect(&selection);
687     EXPECT_EQ(testOnSelect, 1);
688     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
689         ViewStackProcessor::GetInstance()->elementsStack_.pop();
690     }
691 }
692 
693 /**
694  * @tc.name: RichEditorModel009
695  * @tc.desc: test set on text selection change
696  * @tc.type: FUNC
697  */
698 HWTEST_F(RichEditorTestNg, RichEditorModel009, TestSize.Level1)
699 {
700     RichEditorModelNG richEditorModel;
701     richEditorModel.Create();
__anon814dfc0d0e02(const BaseEventInfo* info) 702     auto func = [](const BaseEventInfo* info) {
703         const auto* selectionRange = TypeInfoHelper::DynamicCast<SelectionRangeInfo>(info);
704         ASSERT_NE(selectionRange, nullptr);
705         testSelectionRange = *selectionRange;
706     };
707     richEditorModel.SetOnSelectionChange(std::move(func));
708     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
709     ASSERT_NE(richEditorNode, nullptr);
710     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
711     ASSERT_NE(richEditorPattern, nullptr);
712     ClearSpan();
713     auto focusHub = richEditorPattern->GetFocusHub();
714     ASSERT_NE(focusHub, nullptr);
715     focusHub->RequestFocusImmediately();
716 
717     // insert value 1
718     richEditorPattern->InsertValue(INIT_VALUE_1);
719     EXPECT_EQ(testSelectionRange.start_, 6);
720     EXPECT_EQ(testSelectionRange.end_, 6);
721 
722     // insert value 2
723     richEditorPattern->InsertValue(INIT_VALUE_1);
724     EXPECT_EQ(testSelectionRange.start_, 12);
725     EXPECT_EQ(testSelectionRange.end_, 12);
726 
727     // set caret position
728     richEditorPattern->SetCaretPosition(3);
729     EXPECT_EQ(testSelectionRange.start_, 3);
730     EXPECT_EQ(testSelectionRange.end_, 3);
731 
732     // update selector
733     richEditorPattern->textSelector_.Update(0, 10);
734     EXPECT_EQ(testSelectionRange.start_, 0);
735     EXPECT_EQ(testSelectionRange.end_, 10);
736 
737     // update selector, reverse handle
738     richEditorPattern->textSelector_.Update(10, 8);
739     EXPECT_EQ(testSelectionRange.start_, 8);
740     EXPECT_EQ(testSelectionRange.end_, 10);
741 
742     // select all
743     richEditorPattern->HandleOnSelectAll();
744     EXPECT_EQ(testSelectionRange.start_, 0);
745     EXPECT_EQ(testSelectionRange.end_, 12);
746 
747     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
748         ViewStackProcessor::GetInstance()->elementsStack_.pop();
749     }
750 }
751 
752 /**
753  * @tc.name: RichEditorModel010
754  * @tc.desc: test set on text/image/symbol selection change
755  * @tc.type: FUNC
756  */
757 HWTEST_F(RichEditorTestNg, RichEditorModel010, TestSize.Level1)
758 {
759     RichEditorModelNG richEditorModel;
760     richEditorModel.Create();
__anon814dfc0d0f02(const BaseEventInfo* info) 761     auto func = [](const BaseEventInfo* info) {
762         const auto* selectionRange = TypeInfoHelper::DynamicCast<SelectionRangeInfo>(info);
763         ASSERT_NE(selectionRange, nullptr);
764         testSelectionRange = *selectionRange;
765     };
766     richEditorModel.SetOnSelectionChange(std::move(func));
767     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
768     ASSERT_NE(richEditorNode, nullptr);
769     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
770     ASSERT_NE(richEditorPattern, nullptr);
771     ClearSpan();
772     auto focusHub = richEditorPattern->GetFocusHub();
773     ASSERT_NE(focusHub, nullptr);
774     focusHub->RequestFocusImmediately();
775 
776     // insert value
777     richEditorPattern->InsertValue(INIT_VALUE_1);
778 
779     // add image
780     ImageSpanOptions imageSpanOptions;
781     richEditorPattern->AddImageSpan(imageSpanOptions);
782     richEditorPattern->HandleOnSelectAll();
783     EXPECT_EQ(testSelectionRange.start_, 0);
784     EXPECT_EQ(testSelectionRange.end_, 7);
785 
786     // add symbol
787     SymbolSpanOptions symbolSpanOptions;
788     symbolSpanOptions.symbolId = SYMBOL_ID;
789     auto richEditorController =  richEditorPattern->GetRichEditorController();
790     ASSERT_NE(richEditorController, nullptr);
791     richEditorController->AddSymbolSpan(symbolSpanOptions);
792     richEditorPattern->HandleOnSelectAll();
793     EXPECT_EQ(testSelectionRange.start_, 0);
794     EXPECT_EQ(testSelectionRange.end_, 9);
795 
796     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
797         ViewStackProcessor::GetInstance()->elementsStack_.pop();
798     }
799 }
800 
801 /**
802  * @tc.name: RichEditorModel011
803  * @tc.desc: test placeholder appear and disappear
804  * @tc.type: FUNC
805  */
806 HWTEST_F(RichEditorTestNg, RichEditorModel011, TestSize.Level1)
807 {
808     RichEditorModelNG richEditorModel;
809     richEditorModel.Create();
810     PlaceholderOptions options;
811     options.value = INIT_VALUE_1;
812     richEditorModel.SetPlaceholder(options);
813 
814     auto richEditorNode = AceType::Claim(ViewStackProcessor::GetInstance()->GetMainFrameNode());
815     ASSERT_NE(richEditorNode, nullptr);
816     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
817     ASSERT_NE(richEditorPattern, nullptr);
818     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
819     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
820     auto richEditorController = richEditorPattern->GetRichEditorController();
821     ASSERT_NE(richEditorController, nullptr);
822     LayoutConstraintF parentLayoutConstraint;
823     parentLayoutConstraint.maxSize = CONTAINER_SIZE;
824     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(
825         richEditorNode, AceType::MakeRefPtr<GeometryNode>(), richEditorNode->GetLayoutProperty());
826     ASSERT_NE(layoutWrapper, nullptr);
827     auto layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
828     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
829 
830     // test placeholder appear when there is nothing in richEditor
831     layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
832     auto spanItemChildren = layoutAlgorithm->GetSpans();
833     EXPECT_EQ(spanItemChildren.size(), 0);
834 
835     // test add Text then placeholder disappear
836     TextSpanOptions textOptions;
837     textOptions.value = INIT_VALUE_2;
838     richEditorController->AddTextSpan(textOptions);
839     layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
840     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
841     layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
842     spanItemChildren = layoutAlgorithm->GetSpans();
843     EXPECT_EQ(spanItemChildren.size(), 1);
844     EXPECT_EQ(spanItemChildren.back()->GetSpanContent(), INIT_VALUE_2);
845 
846     // test when richEitor empty again,placeholder Appear again
847     RangeOptions rangeoptions;
848     richEditorController->DeleteSpans(rangeoptions);
849     richEditorPattern->BeforeCreateLayoutWrapper();
850     layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
851     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
852     layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
853     spanItemChildren = layoutAlgorithm->GetSpans();
854     EXPECT_EQ(spanItemChildren.size(), 0);
855 
856     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
857         ViewStackProcessor::GetInstance()->elementsStack_.pop();
858     }
859 }
860 
861 /**
862  * @tc.name: RichEditorModel012
863  * @tc.desc: test placeholder styel value
864  * @tc.type: FUNC
865  */
866 HWTEST_F(RichEditorTestNg, RichEditorModel012, TestSize.Level1)
867 {
868     RichEditorModelNG richEditorModel;
869     richEditorModel.Create();
870     PlaceholderOptions options;
871     options.value = INIT_VALUE_1;
872     options.fontColor = TEXT_COLOR_VALUE;
873     options.fontSize = FONT_SIZE_VALUE;
874     options.fontStyle = ITALIC_FONT_STYLE_VALUE;
875     options.fontWeight = FONT_WEIGHT_VALUE;
876     options.fontFamilies = FONT_FAMILY_VALUE;
877     richEditorModel.SetPlaceholder(options);
878 
879     auto richEditorNode = AceType::Claim(ViewStackProcessor::GetInstance()->GetMainFrameNode());
880     ASSERT_NE(richEditorNode, nullptr);
881     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
882     ASSERT_NE(richEditorPattern, nullptr);
883     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
884     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
885     auto richEditorController = richEditorPattern->GetRichEditorController();
886     ASSERT_NE(richEditorController, nullptr);
887     LayoutConstraintF parentLayoutConstraint;
888     parentLayoutConstraint.maxSize = CONTAINER_SIZE;
889     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(
890         richEditorNode, AceType::MakeRefPtr<GeometryNode>(), richEditorNode->GetLayoutProperty());
891     ASSERT_NE(layoutWrapper, nullptr);
892     auto layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
893     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
894 
895     // test placeholder value and style is correct
896     layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
897     auto spanItemChildren = layoutAlgorithm->GetSpans();
898     EXPECT_EQ(spanItemChildren.size(), 0);
899 
900     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
901         ViewStackProcessor::GetInstance()->elementsStack_.pop();
902     }
903 }
904 
905 /**
906  * @tc.name: RichEditorModel013
907  * @tc.desc: test placeholder styel value
908  * @tc.type: FUNC
909  */
910 HWTEST_F(RichEditorTestNg, RichEditorModel013, TestSize.Level1)
911 {
912     RichEditorModelNG richEditorModel;
913     richEditorModel.Create();
914     PlaceholderOptions options;
915     options.value = INIT_VALUE_1;
916     richEditorModel.SetPlaceholder(options);
917 
918     auto richEditorNode = AceType::Claim(ViewStackProcessor::GetInstance()->GetMainFrameNode());
919     ASSERT_NE(richEditorNode, nullptr);
920     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
921     ASSERT_NE(richEditorPattern, nullptr);
922     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
923     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
924     auto richEditorController = richEditorPattern->GetRichEditorController();
925     ASSERT_NE(richEditorController, nullptr);
926     LayoutConstraintF parentLayoutConstraint;
927     parentLayoutConstraint.maxSize = CONTAINER_SIZE;
928     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(
929         richEditorNode, AceType::MakeRefPtr<GeometryNode>(), richEditorNode->GetLayoutProperty());
930     ASSERT_NE(layoutWrapper, nullptr);
931     auto layoutAlgorithm = AceType::DynamicCast<RichEditorLayoutAlgorithm>(richEditorPattern->CreateLayoutAlgorithm());
932     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
933 
934     // test placeholder value and style is correct
935     layoutAlgorithm->MeasureContent(parentLayoutConstraint, AceType::RawPtr(layoutWrapper));
936     auto spanItemChildren = layoutAlgorithm->GetSpans();
937     EXPECT_EQ(spanItemChildren.size(), 0);
938 
939     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
940         ViewStackProcessor::GetInstance()->elementsStack_.pop();
941     }
942 }
943 
944 /**
945  * @tc.name: RichEditorModel014
946  * @tc.desc: test paragraph style wordBreak attribute
947  * @tc.type: FUNC
948  */
949 HWTEST_F(RichEditorTestNg, RichEditorModel014, TestSize.Level1)
950 {
951     ASSERT_NE(richEditorNode_, nullptr);
952     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
953     ASSERT_NE(richEditorPattern, nullptr);
954     auto richEditorController = richEditorPattern->GetRichEditorController();
955     ASSERT_NE(richEditorController, nullptr);
956     TextSpanOptions options;
957     options.value = INIT_VALUE_1;
958 
959     // test paragraph  style wordBreak default value
960     richEditorController->AddTextSpan(options);
961     auto info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
962     EXPECT_EQ(static_cast<WordBreak>(info[0].wordBreak), WordBreak::BREAK_WORD);
963 
964     // test paragraph style wordBreak value of WordBreak.NORMAL
965     struct UpdateParagraphStyle style;
966     style.wordBreak = WordBreak::NORMAL;
967     richEditorController->UpdateParagraphStyle(1, sizeof(INIT_VALUE_1), style);
968     info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
969     EXPECT_EQ(static_cast<WordBreak>(info[0].wordBreak), WordBreak::NORMAL);
970 
971     // test paragraph style wordBreak value of WordBreak.BREAK_ALL
972     style.wordBreak = WordBreak::BREAK_ALL;
973     richEditorController->UpdateParagraphStyle(1, sizeof(INIT_VALUE_1), style);
974     info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
975     EXPECT_EQ(static_cast<WordBreak>(info[0].wordBreak), WordBreak::BREAK_ALL);
976 
977     // test paragraph style wordBreak value of WordBreak.BREAK_WORD
978     style.wordBreak = WordBreak::BREAK_WORD;
979     richEditorController->UpdateParagraphStyle(1, sizeof(INIT_VALUE_1), style);
980     info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
981     EXPECT_EQ(static_cast<WordBreak>(info[0].wordBreak), WordBreak::BREAK_WORD);
982 }
983 
984 /**
985  * @tc.name: RichEditorModel015
986  * @tc.desc: test textstyle Color
987  * @tc.type: FUNC
988  */
989 HWTEST_F(RichEditorTestNg, RichEditorModel015, TestSize.Level1)
990 {
991     ASSERT_NE(richEditorNode_, nullptr);
992     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
993     ASSERT_NE(richEditorPattern, nullptr);
994     auto richEditorController = richEditorPattern->GetRichEditorController();
995     ASSERT_NE(richEditorController, nullptr);
996 
997     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
998     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
999     auto richEditorTheme = AceType::MakeRefPtr<RichEditorTheme>();
1000     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(richEditorTheme));
1001     richEditorTheme->textStyle_.SetTextColor(DEFAULT_TEXT_COLOR_VALUE);
1002     richEditorTheme->textStyle_.SetTextDecorationColor(DEFAULT_TEXT_COLOR_VALUE);
1003 
1004     TextSpanOptions textOptions;
1005     textOptions.value = INIT_VALUE_1;
1006     richEditorController->AddTextSpan(textOptions);
1007     auto info1 = richEditorController->GetSpansInfo(1, 3);
1008     TextStyleResult textStyle1 = info1.selection_.resultObjects.front().textStyle;
1009     EXPECT_EQ(textStyle1.fontSize, 16);
1010     EXPECT_EQ(Color::FromString(textStyle1.fontColor), DEFAULT_TEXT_COLOR_VALUE);
1011     EXPECT_EQ(Color::FromString(textStyle1.decorationColor), DEFAULT_TEXT_COLOR_VALUE);
1012 
1013     ClearSpan();
1014     richEditorPattern->InsertValue(INIT_VALUE_2);
1015     auto info2 = richEditorController->GetSpansInfo(1, 2);
1016     TextStyleResult textStyle2 = info2.selection_.resultObjects.front().textStyle;
1017     EXPECT_EQ(Color::FromString(textStyle2.fontColor), DEFAULT_TEXT_COLOR_VALUE);
1018     EXPECT_EQ(Color::FromString(textStyle2.decorationColor), DEFAULT_TEXT_COLOR_VALUE);
1019 }
1020 
1021 /**
1022  * @tc.name: RichEditorInsertValue001
1023  * @tc.desc: test calc insert value object
1024  * @tc.type: FUNC
1025  */
1026 HWTEST_F(RichEditorTestNg, RichEditorInsertValue001, TestSize.Level1)
1027 {
1028     ASSERT_NE(richEditorNode_, nullptr);
1029     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1030     ASSERT_NE(richEditorPattern, nullptr);
1031     richEditorPattern->overlayMod_ = AceType::DynamicCast<RichEditorOverlayModifier>(richEditorPattern->overlayMod_);
1032     TextInsertValueInfo info;
1033     richEditorPattern->CalcInsertValueObj(info);
1034     EXPECT_EQ(info.GetSpanIndex(), 0);
1035     EXPECT_EQ(info.GetOffsetInSpan(), 0);
1036     AddSpan(INIT_VALUE_1);
1037     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
1038     richEditorPattern->CalcInsertValueObj(info);
1039     EXPECT_EQ(info.GetSpanIndex(), 1);
1040     EXPECT_EQ(info.GetOffsetInSpan(), 0);
1041 }
1042 
1043 /**
1044  * @tc.name: RichEditorInsertValue002
1045  * @tc.desc: test insert value last
1046  * @tc.type: FUNC
1047  */
1048 HWTEST_F(RichEditorTestNg, RichEditorInsertValue002, TestSize.Level1)
1049 {
1050     ASSERT_NE(richEditorNode_, nullptr);
1051     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1052     ASSERT_NE(richEditorPattern, nullptr);
1053     richEditorPattern->caretPosition_ = 0;
1054     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
1055     auto it1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
1056     const std::string result1 = TEST_INSERT_VALUE;
1057     EXPECT_EQ(result1, it1->spanItem_->content);
1058     ClearSpan();
1059     AddSpan(INIT_VALUE_1);
1060     richEditorPattern->caretPosition_ = 1;
1061     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
1062     auto it2 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
1063     ClearSpan();
1064     AddSpan(INIT_VALUE_1);
1065     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
1066     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
1067     auto it3 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
1068     const std::string result3 = INIT_VALUE_1 + TEST_INSERT_VALUE;
1069     EXPECT_EQ(result3, it3->spanItem_->content);
1070     ClearSpan();
1071     AddImageSpan();
1072     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
1073     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
1074     auto it4 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
1075     const std::string result4 = TEST_INSERT_VALUE;
1076     EXPECT_EQ(result4, it4->spanItem_->content);
1077     ClearSpan();
1078     richEditorPattern->InsertValue(" ");
1079     auto it5 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
1080     EXPECT_TRUE(it5);
1081 }
1082 
1083 /**
1084  * @tc.name: RichEditorInsertValue004
1085  * @tc.desc: test insert value first
1086  * @tc.type: FUNC
1087  */
1088 HWTEST_F(RichEditorTestNg, RichEditorInsertValue004, TestSize.Level1)
1089 {
1090     ASSERT_NE(richEditorNode_, nullptr);
1091     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1092     ASSERT_NE(richEditorPattern, nullptr);
1093     AddImageSpan();
1094     richEditorPattern->caretPosition_ = 0;
1095     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
1096     auto it1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetFirstChild());
1097     const std::string result1 = TEST_INSERT_VALUE;
1098     EXPECT_EQ(result1, it1->spanItem_->content);
1099 }
1100 
1101 /**
1102  * @tc.name: RichEditorInsertValue005
1103  * @tc.desc: test insert value if the insert char is line separator
1104  * @tc.type: FUNC
1105  */
1106 HWTEST_F(RichEditorTestNg, RichEditorInsertValue005, TestSize.Level1)
1107 {
1108     ASSERT_NE(richEditorNode_, nullptr);
1109     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1110     ASSERT_NE(richEditorPattern, nullptr);
1111     AddSpan(INIT_VALUE_1);
1112     richEditorPattern->caretPosition_ = 0;
1113     richEditorPattern->moveLength_ = 0;
1114     richEditorPattern->InsertValue(TEST_INSERT_LINE_SEP);
1115     auto it1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
1116     const std::string result1 = INIT_VALUE_1;
1117     EXPECT_EQ(result1, it1->spanItem_->content);
1118     ClearSpan();
1119     AddSpan(INIT_VALUE_1);
1120     richEditorPattern->caretPosition_ = 1;
1121     richEditorPattern->moveLength_ = 0;
1122     richEditorPattern->InsertValue(TEST_INSERT_LINE_SEP);
1123     auto it2 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetFirstChild());
1124     const std::string result2 = EXCEPT_VALUE;
1125     EXPECT_EQ(result2, it2->spanItem_->content);
1126 }
1127 
1128 /**
1129  * @tc.name: RichEditorDelete001
1130  * @tc.desc: test delete forward
1131  * @tc.type: FUNC
1132  */
1133 HWTEST_F(RichEditorTestNg, RichEditorDelete001, TestSize.Level1)
1134 {
1135     ASSERT_NE(richEditorNode_, nullptr);
1136     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1137     ASSERT_NE(richEditorPattern, nullptr);
1138     AddImageSpan();
1139     richEditorPattern->caretPosition_ = 0;
1140     richEditorPattern->DeleteForward(1);
1141     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
1142     ClearSpan();
1143     AddSpan(INIT_VALUE_1);
1144     richEditorPattern->caretPosition_ = 0;
1145     richEditorPattern->DeleteForward(7);
1146     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
1147 }
1148 
1149 /**
1150  * @tc.name: RichEditorDelete002
1151  * @tc.desc: test delete backforward
1152  * @tc.type: FUNC
1153  */
1154 HWTEST_F(RichEditorTestNg, RichEditorDelete002, TestSize.Level1)
1155 {
1156     ASSERT_NE(richEditorNode_, nullptr);
1157     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1158     ASSERT_NE(richEditorPattern, nullptr);
1159     AddImageSpan();
1160     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
1161     richEditorPattern->DeleteBackward(1);
1162     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
1163     ClearSpan();
1164     AddSpan(INIT_VALUE_1);
1165     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
1166     richEditorPattern->DeleteBackward(6);
1167     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
1168 }
1169 
1170 /**
1171  * @tc.name: RichEditorDelete003
1172  * @tc.desc: test delete backforward
1173  * @tc.type: FUNC
1174  */
1175 HWTEST_F(RichEditorTestNg, RichEditorDelete003, TestSize.Level1)
1176 {
1177     ASSERT_NE(richEditorNode_, nullptr);
1178     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1179     ASSERT_NE(richEditorPattern, nullptr);
1180     AddImageSpan();
1181     richEditorPattern->caretPosition_ = 0;
1182     richEditorPattern->DeleteBackward(1);
1183     EXPECT_NE(richEditorNode_->GetChildren().size(), 0);
1184     richEditorPattern->textSelector_ = TextSelector(0, 1);
1185     richEditorPattern->caretPosition_ = 1;
1186     richEditorPattern->DeleteBackward(1);
1187     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
1188     while (!richEditorPattern->spans_.empty()) {
1189         richEditorPattern->spans_.pop_back();
1190     }
1191     richEditorPattern->DeleteBackward(1);
1192     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
1193 }
1194 
1195 /**
1196  * @tc.name: RichEditorDeleteForwardEmoji
1197  * @tc.desc: test DeleteForward Emoji And Emoji Selected
1198  * @tc.type: FUNC
1199  */
1200 HWTEST_F(RichEditorTestNg, RichEditorDeleteForwardEmoji, TestSize.Level1)
1201 {
1202     ASSERT_NE(richEditorNode_, nullptr);
1203     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1204     ASSERT_NE(richEditorPattern, nullptr);
1205     AddSpan("��3����");
1206     richEditorPattern->caretPosition_ = 2;
1207     richEditorPattern->textSelector_ = TextSelector(2, 5);
1208     richEditorPattern->DeleteForward(1);
1209     ASSERT_EQ(richEditorPattern->caretPosition_, 2);
1210     richEditorPattern->DeleteForward(1);
1211     ASSERT_EQ(richEditorPattern->caretPosition_, 2);
1212 }
1213 
1214 /**
1215  * @tc.name: RichEditorDeleteBackwardEmoji
1216  * @tc.desc: test DeleteBackward Emoji And Emoji Selected
1217  * @tc.type: FUNC
1218  */
1219 HWTEST_F(RichEditorTestNg, RichEditorDeleteBackwardEmoji, TestSize.Level1)
1220 {
1221     ASSERT_NE(richEditorNode_, nullptr);
1222     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1223     ASSERT_NE(richEditorPattern, nullptr);
1224     AddSpan("��3����");
1225     richEditorPattern->caretPosition_ = 2;
1226     richEditorPattern->textSelector_ = TextSelector(2, 5);
1227     richEditorPattern->DeleteBackward(1);
1228     ASSERT_EQ(richEditorPattern->caretPosition_, 2);
1229     richEditorPattern->DeleteBackward(1);
1230     ASSERT_EQ(richEditorPattern->caretPosition_, 0);
1231 }
1232 
1233 /**
1234  * @tc.name: RichEditorController001
1235  * @tc.desc: test add image span
1236  * @tc.type: FUNC
1237  */
1238 HWTEST_F(RichEditorTestNg, RichEditorController001, TestSize.Level1)
1239 {
1240     ASSERT_NE(richEditorNode_, nullptr);
1241     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1242     ASSERT_NE(richEditorPattern, nullptr);
1243     auto richEditorController = richEditorPattern->GetRichEditorController();
1244     ASSERT_NE(richEditorController, nullptr);
1245     ImageSpanAttribute imageStyle;
1246     AddSpan("test");
1247     ImageSpanOptions options;
1248     options.imageAttribute = imageStyle;
1249     options.image = IMAGE_VALUE;
1250     options.bundleName = BUNDLE_NAME;
1251     options.moduleName = MODULE_NAME;
1252     options.offset = 1;
1253     auto index1 = richEditorController->AddImageSpan(options);
1254     EXPECT_EQ(index1, 1);
1255     options.image = IMAGE_VALUE;
1256     options.bundleName = BUNDLE_NAME;
1257     options.moduleName = MODULE_NAME;
1258     options.offset = 2;
1259     auto index2 = richEditorController->AddImageSpan(options);
1260     EXPECT_EQ(index2, 2);
1261 
1262     options.offset = std::nullopt;
1263     auto index3 = richEditorPattern->AddImageSpan(options, false, 0);
1264     EXPECT_EQ(index3, 4);
1265 
1266     std::optional<Ace::NG::MarginProperty> marginProp = std::nullopt;
1267     std::optional<Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt;
1268     imageStyle.marginProp = marginProp;
1269     imageStyle.borderRadius = borderRadius;
1270     options.imageAttribute = imageStyle;
1271     auto index4 = richEditorPattern->AddImageSpan(options, false, 0);
1272     EXPECT_EQ(index4, 5);
1273 
1274     marginProp = { CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC };
1275     borderRadius = { CALC_TEST, CALC_TEST, CALC_TEST, CALC_TEST };
1276     imageStyle.marginProp = marginProp;
1277     imageStyle.borderRadius = borderRadius;
1278     options.imageAttribute = imageStyle;
1279     auto index5 = richEditorPattern->AddImageSpan(options, false, 0);
1280     EXPECT_EQ(index5, 6);
1281 
1282     marginProp = { ERROR_CALC_LENGTH_CALC, ERROR_CALC_LENGTH_CALC, ERROR_CALC_LENGTH_CALC, ERROR_CALC_LENGTH_CALC };
1283     borderRadius = { ERROR_CALC_TEST, ERROR_CALC_TEST, ERROR_CALC_TEST, ERROR_CALC_TEST };
1284     imageStyle.marginProp = marginProp;
1285     imageStyle.borderRadius = borderRadius;
1286     options.imageAttribute = imageStyle;
1287     auto index6 = richEditorPattern->AddImageSpan(options, false, -1);
1288     EXPECT_EQ(index6, 7);
1289 }
1290 
1291 /**
1292  * @tc.name: RichEditorController002
1293  * @tc.desc: test add text span
1294  * @tc.type: FUNC
1295  */
1296 HWTEST_F(RichEditorTestNg, RichEditorController002, TestSize.Level1)
1297 {
1298     ASSERT_NE(richEditorNode_, nullptr);
1299     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1300     ASSERT_NE(richEditorPattern, nullptr);
1301     auto richEditorController = richEditorPattern->GetRichEditorController();
1302     ASSERT_NE(richEditorController, nullptr);
1303     TextStyle style;
1304     style.SetTextColor(TEXT_COLOR_VALUE);
1305     style.SetFontSize(FONT_SIZE_VALUE);
1306     style.SetFontStyle(ITALIC_FONT_STYLE_VALUE);
1307     style.SetFontWeight(FONT_WEIGHT_VALUE);
1308     style.SetFontFamilies(FONT_FAMILY_VALUE);
1309     style.SetTextDecoration(TEXT_DECORATION_VALUE);
1310     style.SetTextDecorationColor(TEXT_DECORATION_COLOR_VALUE);
1311     TextSpanOptions options;
1312     options.offset = 1;
1313     options.value = INIT_VALUE_1;
1314     options.style = style;
1315     auto index1 = richEditorController->AddTextSpan(options);
1316     EXPECT_EQ(index1, 0);
1317     auto index2 = richEditorController->AddTextSpan(options);
1318     EXPECT_EQ(index2, 1);
1319     options.value = "hello\n";
1320     auto index3 = richEditorController->AddTextSpan(options);
1321     EXPECT_EQ(index3, 1);
1322 }
1323 
1324 /**
1325  * @tc.name: OnCaretTwinkling001
1326  * @tc.desc: test on caret twinkling
1327  * @tc.type: FUNC
1328  */
1329 HWTEST_F(RichEditorTestNg, OnCaretTwinkling001, TestSize.Level1)
1330 {
1331     ASSERT_NE(richEditorNode_, nullptr);
1332     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1333     ASSERT_NE(richEditorPattern, nullptr);
1334     richEditorPattern->caretVisible_ = true;
1335     richEditorPattern->OnCaretTwinkling();
1336     EXPECT_FALSE(richEditorPattern->caretVisible_);
1337 }
1338 
1339 /**
1340  * @tc.name: RichEditorController003
1341  * @tc.desc: test get caret offset
1342  * @tc.type: FUNC
1343  */
1344 HWTEST_F(RichEditorTestNg, RichEditorController003, TestSize.Level1)
1345 {
1346     ASSERT_NE(richEditorNode_, nullptr);
1347     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1348     ASSERT_NE(richEditorPattern, nullptr);
1349     auto richEditorController = richEditorPattern->GetRichEditorController();
1350     ASSERT_NE(richEditorController, nullptr);
1351     AddSpan(INIT_VALUE_1);
1352     richEditorPattern->caretPosition_ = 1;
1353     auto offset1 = richEditorController->GetCaretOffset();
1354     EXPECT_EQ(offset1, 1);
1355     richEditorPattern->caretPosition_ = 2;
1356     auto offset2 = richEditorController->GetCaretOffset();
1357     EXPECT_EQ(offset2, 2);
1358 }
1359 
1360 /**
1361  * @tc.name: RichEditorController004
1362  * @tc.desc: test set caret offset
1363  * @tc.type: FUNC
1364  */
1365 HWTEST_F(RichEditorTestNg, RichEditorController004, TestSize.Level1)
1366 {
1367     ASSERT_NE(richEditorNode_, nullptr);
1368     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1369     ASSERT_NE(richEditorPattern, nullptr);
1370     auto richEditorController = richEditorPattern->GetRichEditorController();
1371     ASSERT_NE(richEditorController, nullptr);
1372     AddSpan(INIT_VALUE_1);
1373     richEditorController->SetCaretOffset(2);
1374     EXPECT_EQ(richEditorPattern->caretPosition_, 2);
1375     richEditorController->SetCaretOffset(-1);
1376     EXPECT_EQ(richEditorPattern->caretPosition_, 2);
1377 }
1378 
1379 /**
1380  * @tc.name: RichEditorController005
1381  * @tc.desc: test update span style
1382  * @tc.type: FUNC
1383  */
1384 HWTEST_F(RichEditorTestNg, RichEditorController005, TestSize.Level1)
1385 {
1386     ASSERT_NE(richEditorNode_, nullptr);
1387     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1388     ASSERT_NE(richEditorPattern, nullptr);
1389     auto richEditorController = richEditorPattern->GetRichEditorController();
1390     ASSERT_NE(richEditorController, nullptr);
1391     AddSpan(INIT_VALUE_1);
1392     AddImageSpan();
1393     AddSpan(INIT_VALUE_2);
1394     TextStyle textStyle;
1395     ImageSpanAttribute imageStyle;
1396     textStyle.SetTextColor(TEXT_COLOR_VALUE);
1397     textStyle.SetTextShadows(SHADOWS);
1398     textStyle.SetFontSize(FONT_SIZE_VALUE);
1399     textStyle.SetFontStyle(ITALIC_FONT_STYLE_VALUE);
1400     textStyle.SetFontWeight(FONT_WEIGHT_VALUE);
1401     textStyle.SetFontFamilies(FONT_FAMILY_VALUE);
1402     textStyle.SetTextDecoration(TEXT_DECORATION_VALUE);
1403     textStyle.SetTextDecorationColor(TEXT_DECORATION_COLOR_VALUE);
1404     struct UpdateSpanStyle updateSpanStyle;
1405     updateSpanStyle.updateTextColor = TEXT_COLOR_VALUE;
1406     updateSpanStyle.updateTextShadows = SHADOWS;
1407     updateSpanStyle.updateFontSize = FONT_SIZE_VALUE;
1408     updateSpanStyle.updateItalicFontStyle = ITALIC_FONT_STYLE_VALUE;
1409     updateSpanStyle.updateFontWeight = FONT_WEIGHT_VALUE;
1410     updateSpanStyle.updateFontFamily = FONT_FAMILY_VALUE;
1411     updateSpanStyle.updateTextDecoration = TEXT_DECORATION_VALUE;
1412     updateSpanStyle.updateTextDecorationColor = TEXT_DECORATION_COLOR_VALUE;
1413     richEditorController->SetUpdateSpanStyle(updateSpanStyle);
1414     richEditorController->UpdateSpanStyle(5, 10, textStyle, imageStyle);
1415     EXPECT_EQ(richEditorNode_->GetChildren().size(), 5);
1416     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(1));
1417     ASSERT_NE(newSpan1, nullptr);
1418     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE);
1419     EXPECT_EQ(newSpan1->GetTextColor(), TEXT_COLOR_VALUE);
1420     EXPECT_EQ(newSpan1->GetTextShadow(), SHADOWS);
1421     EXPECT_EQ(newSpan1->GetItalicFontStyle(), ITALIC_FONT_STYLE_VALUE);
1422     EXPECT_EQ(newSpan1->GetFontWeight(), FONT_WEIGHT_VALUE);
1423     EXPECT_EQ(newSpan1->GetFontFamily(), FONT_FAMILY_VALUE);
1424     EXPECT_EQ(newSpan1->GetTextDecoration(), TEXT_DECORATION_VALUE);
1425     EXPECT_EQ(newSpan1->GetTextDecorationColor(), TEXT_DECORATION_COLOR_VALUE);
1426     auto newSpan2 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(3));
1427     ASSERT_NE(newSpan2, nullptr);
1428     EXPECT_EQ(newSpan2->GetFontSize(), FONT_SIZE_VALUE);
1429     EXPECT_EQ(newSpan2->GetTextColor(), TEXT_COLOR_VALUE);
1430     EXPECT_EQ(newSpan2->GetTextShadow(), SHADOWS);
1431     EXPECT_EQ(newSpan2->GetItalicFontStyle(), ITALIC_FONT_STYLE_VALUE);
1432     EXPECT_EQ(newSpan2->GetFontWeight(), FONT_WEIGHT_VALUE);
1433     EXPECT_EQ(newSpan2->GetFontFamily(), FONT_FAMILY_VALUE);
1434     EXPECT_EQ(newSpan2->GetTextDecoration(), TEXT_DECORATION_VALUE);
1435     EXPECT_EQ(newSpan2->GetTextDecorationColor(), TEXT_DECORATION_COLOR_VALUE);
1436 }
1437 
1438 /**
1439  * @tc.name: RichEditorController006
1440  * @tc.desc: test get span info
1441  * @tc.type: FUNC
1442  */
1443 HWTEST_F(RichEditorTestNg, RichEditorController006, TestSize.Level1)
1444 {
1445     ASSERT_NE(richEditorNode_, nullptr);
1446     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1447     ASSERT_NE(richEditorPattern, nullptr);
1448     auto richEditorController = richEditorPattern->GetRichEditorController();
1449     ASSERT_NE(richEditorController, nullptr);
1450     AddSpan(INIT_VALUE_1);
1451     AddImageSpan();
1452     AddSpan(INIT_VALUE_2);
1453     auto info1 = richEditorController->GetSpansInfo(1, 10);
1454     EXPECT_EQ(info1.selection_.selection[0], 1);
1455     EXPECT_EQ(info1.selection_.selection[1], 10);
1456     EXPECT_EQ(info1.selection_.resultObjects.size(), 3);
1457     auto info2 = richEditorController->GetSpansInfo(10, 1);
1458     EXPECT_EQ(info2.selection_.selection[0], 1);
1459     EXPECT_EQ(info2.selection_.selection[1], 10);
1460     auto info3 = richEditorController->GetSpansInfo(-1, 10);
1461     EXPECT_EQ(info3.selection_.selection[0], 0);
1462     EXPECT_EQ(info3.selection_.selection[1], 10);
1463     auto info4 = richEditorController->GetSpansInfo(1, -10);
1464     EXPECT_EQ(info4.selection_.selection[0], 0);
1465     EXPECT_EQ(info4.selection_.selection[1], 1);
1466 }
1467 
1468 /**
1469  * @tc.name: RichEditorController007
1470  * @tc.desc: test delete span
1471  * @tc.type: FUNC
1472  */
1473 HWTEST_F(RichEditorTestNg, RichEditorController007, TestSize.Level1)
1474 {
1475     ASSERT_NE(richEditorNode_, nullptr);
1476     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1477     ASSERT_NE(richEditorPattern, nullptr);
1478     auto richEditorController = richEditorPattern->GetRichEditorController();
1479     ASSERT_NE(richEditorController, nullptr);
1480     AddSpan(INIT_VALUE_1);
1481     AddImageSpan();
1482     AddSpan(INIT_VALUE_2);
1483     RangeOptions option1;
1484     option1.start = 5;
1485     option1.end = 10;
1486     richEditorController->DeleteSpans(option1);
1487     EXPECT_EQ(richEditorNode_->GetChildren().size(), 2);
1488     ClearSpan();
1489     AddSpan(INIT_VALUE_1);
1490     AddImageSpan();
1491     AddSpan(INIT_VALUE_2);
1492     RangeOptions option2;
1493     option2.start = 10;
1494     option2.end = 5;
1495     richEditorController->DeleteSpans(option2);
1496     EXPECT_EQ(richEditorNode_->GetChildren().size(), 2);
1497     ClearSpan();
1498     AddSpan(INIT_VALUE_1);
1499     AddImageSpan();
1500     AddSpan(INIT_VALUE_2);
1501     RangeOptions option3;
1502     option3.start = -5;
1503     option3.end = 10;
1504     richEditorController->DeleteSpans(option3);
1505     EXPECT_EQ(richEditorNode_->GetChildren().size(), 1);
1506     ClearSpan();
1507     AddSpan(INIT_VALUE_1);
1508     AddImageSpan();
1509     AddSpan(INIT_VALUE_2);
1510     RangeOptions option4;
1511     option4.start = 5;
1512     option4.end = -10;
1513     richEditorController->DeleteSpans(option4);
1514     EXPECT_EQ(richEditorNode_->GetChildren().size(), 3);
1515     ClearSpan();
1516     AddSpan(INIT_VALUE_1);
1517     AddImageSpan();
1518     AddSpan(INIT_VALUE_2);
1519     RangeOptions option5;
1520     richEditorController->DeleteSpans(option5);
1521     EXPECT_TRUE(richEditorNode_->GetChildren().empty());
1522     ClearSpan();
1523     AddSpan(INIT_VALUE_1);
1524     AddImageSpan();
1525     AddSpan(INIT_VALUE_2);
1526     option5.start = 100;
1527     option5.end = 10;
1528     richEditorController->DeleteSpans(option5);
1529     EXPECT_EQ(richEditorNode_->GetChildren().size(), 3);
1530     ClearSpan();
1531     AddSpan(INIT_VALUE_1);
1532     AddImageSpan();
1533     AddSpan(INIT_VALUE_2);
1534     option5.start = 3;
1535     option5.end = 3;
1536     richEditorController->DeleteSpans(option5);
1537     EXPECT_EQ(richEditorNode_->GetChildren().size(), 3);
1538     ClearSpan();
1539     richEditorController->DeleteSpans(option5);
1540 }
1541 
1542 /**
1543  * @tc.name: OnDirtyLayoutWrapper001
1544  * @tc.desc: test on dirty layout wrapper
1545  * @tc.type: FUNC
1546  */
1547 HWTEST_F(RichEditorTestNg, OnDirtyLayoutWrapper001, TestSize.Level1)
1548 {
1549     ASSERT_NE(richEditorNode_, nullptr);
1550     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1551     ASSERT_NE(richEditorPattern, nullptr);
1552     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(
1553         richEditorNode_, AceType::MakeRefPtr<GeometryNode>(), richEditorNode_->GetLayoutProperty());
1554     ASSERT_NE(layoutWrapper, nullptr);
1555     auto layoutAlgorithm = richEditorPattern->CreateLayoutAlgorithm();
1556     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
1557     DirtySwapConfig config;
1558     config.skipMeasure = true;
1559     auto focusHub = richEditorPattern->GetHost()->GetOrCreateFocusHub();
1560     focusHub->currentFocus_ = true;
1561     auto ret = richEditorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1562     EXPECT_FALSE(ret);
1563     richEditorPattern->isRichEditorInit_ = true;
1564 
1565     richEditorPattern->textSelector_.baseOffset = -1;
1566     richEditorPattern->textSelector_.destinationOffset = 2;
1567     ret = richEditorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1568     EXPECT_FALSE(ret);
1569 
1570     richEditorPattern->textSelector_.baseOffset = 0;
1571     richEditorPattern->textSelector_.destinationOffset = -1;
1572     ret = richEditorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1573     EXPECT_FALSE(ret);
1574 }
1575 
1576 /**
1577  * @tc.name: CreateImageSourceInfo001
1578  * @tc.desc: test CreateImageSourceInfo
1579  * @tc.type: FUNC
1580  */
1581 HWTEST_F(RichEditorTestNg, CreateImageSourceInfo001, TestSize.Level1)
1582 {
1583     ASSERT_NE(richEditorNode_, nullptr);
1584     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1585     ASSERT_NE(richEditorPattern, nullptr);
1586     ImageSpanOptions info;
1587     auto ret = richEditorPattern->CreateImageSourceInfo(info);
1588     EXPECT_NE(ret, nullptr);
1589 }
1590 
1591 /**
1592  * @tc.name: HandleClickEvent001
1593  * @tc.desc: test handle click event
1594  * @tc.type: FUNC
1595  */
1596 HWTEST_F(RichEditorTestNg, HandleClickEvent001, TestSize.Level1)
1597 {
1598     ASSERT_NE(richEditorNode_, nullptr);
1599     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1600     ASSERT_NE(richEditorPattern, nullptr);
1601     GestureEvent info;
1602     info.localLocation_ = Offset(0, 0);
1603     ParagraphStyle paragraphStyle;
1604     auto paragraph = Paragraph::Create(paragraphStyle, FontCollection::Current());
1605     richEditorPattern->pManager_->AddParagraph({ .paragraph = paragraph, .paragraphStyle = paragraphStyle });
1606     richEditorPattern->HandleClickEvent(info);
1607     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
1608 
1609     richEditorPattern->caretPosition_ = 1;
1610     richEditorPattern->textSelector_.baseOffset = -1;
1611     richEditorPattern->textSelector_.destinationOffset = -1;
1612 
1613     richEditorPattern->isMouseSelect_ = true;
1614     richEditorPattern->hasClicked_ = false;
1615     richEditorPattern->HandleClickEvent(info);
1616     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
1617     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
1618     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
1619 
1620     richEditorPattern->caretPosition_ = 1;
1621     richEditorPattern->isMouseSelect_ = false;
1622     richEditorPattern->hasClicked_ = false;
1623     richEditorPattern->HandleClickEvent(info);
1624     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
1625     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
1626     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
1627 
1628     richEditorPattern->caretPosition_ = 1;
1629     richEditorPattern->textSelector_.baseOffset = 0;
1630     richEditorPattern->textSelector_.destinationOffset = 1;
1631 
1632     richEditorPattern->isMouseSelect_ = true;
1633     richEditorPattern->hasClicked_ = false;
1634     richEditorPattern->HandleClickEvent(info);
1635     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
1636     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 1);
1637     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
1638 
1639     richEditorPattern->caretPosition_ = 1;
1640     richEditorPattern->isMouseSelect_ = false;
1641     richEditorPattern->hasClicked_ = false;
1642     richEditorPattern->HandleClickEvent(info);
1643     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
1644     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
1645 }
1646 
1647 /**
1648  * @tc.name: PreventDefault001
1649  * @tc.desc: test PreventDefault001 in ImageSpan and TextSpan
1650  * @tc.type: FUNC
1651  */
1652 HWTEST_F(RichEditorTestNg, PreventDefault001, TestSize.Level1)
1653 {
1654     RichEditorModelNG richEditorModel;
1655     richEditorModel.Create();
1656     auto richEditorNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1657     ASSERT_NE(richEditorNode, nullptr);
1658     auto richEditorPattern = richEditorNode->GetPattern<RichEditorPattern>();
1659     ASSERT_NE(richEditorPattern, nullptr);
1660     auto richEditorController = richEditorPattern->GetRichEditorController();
1661     ASSERT_NE(richEditorController, nullptr);
1662 
1663     // add imageSpan
1664     ClearSpan();
1665     ImageSpanOptions imageSpanOptions;
__anon814dfc0d1002(GestureEvent& info) 1666     GestureEventFunc callback2 = [](GestureEvent& info) {
1667         info.SetPreventDefault(true);
1668     };
1669     imageSpanOptions.userGestureOption.onClick = callback2;
1670     richEditorController->AddImageSpan(imageSpanOptions);
1671 
1672     /**
1673      * @tc.steps: step1. Click on imagespan
1674      */
1675     GestureEvent info2;
1676     info2.localLocation_ = Offset(0, 0);
1677     richEditorPattern->HandleClickEvent(info2);
1678     EXPECT_FALSE(richEditorPattern->HasFocus());
1679 }
1680 
1681 /**
1682  * @tc.name: MoveCaretAfterTextChange001
1683  * @tc.desc: test move caret after text change
1684  * @tc.type: FUNC
1685  */
1686 HWTEST_F(RichEditorTestNg, MoveCaretAfterTextChange001, TestSize.Level1)
1687 {
1688     ASSERT_NE(richEditorNode_, nullptr);
1689     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1690     ASSERT_NE(richEditorPattern, nullptr);
1691     AddSpan(INIT_VALUE_1);
1692     richEditorPattern->isTextChange_ = true;
1693     richEditorPattern->moveLength_ = 1;
1694     richEditorPattern->moveDirection_ = MoveDirection::BACKWARD;
1695     richEditorPattern->caretPosition_ = 5;
1696     richEditorPattern->MoveCaretAfterTextChange();
1697     EXPECT_EQ(richEditorPattern->caretPosition_, 4);
1698     richEditorPattern->isTextChange_ = true;
1699     richEditorPattern->moveDirection_ = MoveDirection::FORWARD;
1700     richEditorPattern->moveLength_ = 1;
1701     richEditorPattern->MoveCaretAfterTextChange();
1702     EXPECT_EQ(richEditorPattern->caretPosition_, 5);
1703     richEditorPattern->isTextChange_ = true;
1704     richEditorPattern->moveDirection_ = MoveDirection(-1);
1705     richEditorPattern->moveLength_ = 1;
1706     richEditorPattern->MoveCaretAfterTextChange();
1707     EXPECT_EQ(richEditorPattern->caretPosition_, 5);
1708 }
1709 
1710 /**
1711  * @tc.name: OnKeyEvent001
1712  * @tc.desc: test OnKeyEvent
1713  * @tc.type: FUNC
1714  */
1715 HWTEST_F(RichEditorTestNg, OnKeyEvent001, TestSize.Level1)
1716 {
1717     ASSERT_NE(richEditorNode_, nullptr);
1718     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1719     ASSERT_NE(richEditorPattern, nullptr);
1720     AddSpan(INIT_VALUE_1);
1721     KeyEvent keyE;
1722     keyE.action = KeyAction::UP;
1723     EXPECT_FALSE(richEditorPattern->OnKeyEvent(keyE));
1724 
1725     keyE.action = KeyAction::DOWN;
1726     keyE.code = KeyCode::KEY_TAB;
1727     EXPECT_FALSE(richEditorPattern->OnKeyEvent(keyE));
1728 
1729     keyE.code = KeyCode::KEY_DEL;
1730     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1731 
1732     keyE.code = KeyCode::KEY_FORWARD_DEL;
1733     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1734 
1735     keyE.code = KeyCode::KEY_ENTER;
1736     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1737 
1738     keyE.code = KeyCode::KEY_NUMPAD_ENTER;
1739     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1740 
1741     keyE.code = KeyCode::KEY_DPAD_CENTER;
1742     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1743 
1744     // 2012 2015
1745     std::vector<KeyCode> cases = { KeyCode::KEY_DPAD_UP, KeyCode::KEY_DPAD_DOWN, KeyCode::KEY_TAB,
1746         KeyCode::KEY_DPAD_RIGHT };
1747     for (int i = 0; i < 4; ++i) {
1748         keyE.code = cases[i];
1749         if (i == 2) {
1750             EXPECT_FALSE(richEditorPattern->OnKeyEvent(keyE));
1751         } else {
1752             EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1753         }
1754     }
1755 
1756     keyE.code = KeyCode::KEY_PRINT;
1757     EXPECT_FALSE(richEditorPattern->OnKeyEvent(keyE));
1758 
1759     keyE.code = KeyCode::KEY_2;
1760     keyE.pressedCodes = { KeyCode::KEY_SHIFT_LEFT };
1761     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1762     keyE.pressedCodes = { KeyCode::KEY_SHIFT_RIGHT };
1763     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1764     keyE.pressedCodes = { KeyCode::KEY_ALT_LEFT };
1765     EXPECT_FALSE(richEditorPattern->OnKeyEvent(keyE));
1766 
1767     keyE.code = KeyCode::KEY_SPACE;
1768     keyE.pressedCodes = { KeyCode::KEY_SHIFT_LEFT };
1769     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1770     keyE.pressedCodes = { KeyCode::KEY_SHIFT_RIGHT };
1771     EXPECT_TRUE(richEditorPattern->OnKeyEvent(keyE));
1772     keyE.pressedCodes = { KeyCode::KEY_ALT_LEFT };
1773     EXPECT_FALSE(richEditorPattern->OnKeyEvent(keyE));
1774 }
1775 
1776 /**
1777  * @tc.name: GetLeftTextOfCursor001
1778  * @tc.desc: test GetLeftTextOfCursor
1779  * @tc.type: FUNC
1780  */
1781 HWTEST_F(RichEditorTestNg, GetLeftTextOfCursor001, TestSize.Level1)
1782 {
1783     ASSERT_NE(richEditorNode_, nullptr);
1784     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1785     richEditorPattern->textForDisplay_ = "tesol";
1786     ASSERT_NE(richEditorPattern, nullptr);
1787     richEditorPattern->caretPosition_ = 1;
1788     richEditorPattern->textSelector_.baseOffset = 2;
1789     richEditorPattern->textSelector_.destinationOffset = 3;
1790     auto ret = StringUtils::Str16ToStr8(richEditorPattern->GetLeftTextOfCursor(1));
1791     EXPECT_EQ(ret, "e");
1792 
1793     ret = StringUtils::Str16ToStr8(richEditorPattern->GetLeftTextOfCursor(2));
1794     EXPECT_EQ(ret, "e");
1795 
1796     richEditorPattern->textSelector_.baseOffset = 2;
1797     richEditorPattern->textSelector_.destinationOffset = 2;
1798     ret = StringUtils::Str16ToStr8(richEditorPattern->GetLeftTextOfCursor(1));
1799     EXPECT_EQ(ret, "t");
1800 
1801     richEditorPattern->textSelector_.baseOffset = 3;
1802     richEditorPattern->textSelector_.destinationOffset = 2;
1803     ret = StringUtils::Str16ToStr8(richEditorPattern->GetLeftTextOfCursor(1));
1804     EXPECT_EQ(ret, "e");
1805 }
1806 
1807 /**
1808  * @tc.name: GetRightTextOfCursor001
1809  * @tc.desc: test GetRightTextOfCursor
1810  * @tc.type: FUNC
1811  */
1812 HWTEST_F(RichEditorTestNg, GetRightTextOfCursor001, TestSize.Level1)
1813 {
1814     ASSERT_NE(richEditorNode_, nullptr);
1815     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1816     richEditorPattern->textForDisplay_ = "tesol";
1817     ASSERT_NE(richEditorPattern, nullptr);
1818     richEditorPattern->caretPosition_ = 1;
1819     richEditorPattern->textSelector_.baseOffset = 2;
1820     richEditorPattern->textSelector_.destinationOffset = 3;
1821     auto ret = StringUtils::Str16ToStr8(richEditorPattern->GetRightTextOfCursor(2));
1822     EXPECT_EQ(ret, "ol");
1823 
1824     richEditorPattern->textSelector_.baseOffset = 2;
1825     richEditorPattern->textSelector_.destinationOffset = 2;
1826     ret = StringUtils::Str16ToStr8(richEditorPattern->GetRightTextOfCursor(2));
1827     EXPECT_EQ(ret, "es");
1828 }
1829 
1830 /**
1831  * @tc.name: GetRightTextOfCursor002
1832  * @tc.desc: test get right text of cursor
1833  * @tc.type: FUNC
1834  */
1835 HWTEST_F(RichEditorTestNg, GetRightTextOfCursor002, TestSize.Level1)
1836 {
1837     ASSERT_NE(richEditorNode_, nullptr);
1838     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1839     ASSERT_NE(richEditorPattern, nullptr);
1840     AddSpan(INIT_VALUE_1);
1841     auto ret = StringUtils::Str16ToStr8(richEditorPattern->GetRightTextOfCursor(3));
1842     EXPECT_EQ(ret, "hel");
1843 }
1844 
1845 /**
1846  * @tc.name: GetTextIndexAtCursor001
1847  * @tc.desc: test get text index at cursor
1848  * @tc.type: FUNC
1849  */
1850 HWTEST_F(RichEditorTestNg, GetTextIndexAtCursor001, TestSize.Level1)
1851 {
1852     ASSERT_NE(richEditorNode_, nullptr);
1853     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1854     ASSERT_NE(richEditorPattern, nullptr);
1855     AddSpan(INIT_VALUE_1);
1856     richEditorPattern->caretPosition_ = 3;
1857     EXPECT_EQ(richEditorPattern->GetTextIndexAtCursor(), 3);
1858 }
1859 
1860 /**
1861  * @tc.name: InitSelection001
1862  * @tc.desc: test InitSelection
1863  * @tc.type: FUNC
1864  */
1865 HWTEST_F(RichEditorTestNg, InitSelection001, TestSize.Level1)
1866 {
1867     ASSERT_NE(richEditorNode_, nullptr);
1868     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1869     ASSERT_NE(richEditorPattern, nullptr);
1870     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1871     richEditorPattern->paragraphs_.paragraphs_.push_front({ paragraph });
1872     richEditorPattern->textForDisplay_ = "test";
1873     richEditorPattern->InitSelection(Offset(0, 0));
1874     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
1875     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 0);
1876 }
1877 
1878 /**
1879  * @tc.name: InitSelection002
1880  * @tc.desc: test InitSelection
1881  * @tc.type: FUNC
1882  */
1883 HWTEST_F(RichEditorTestNg, InitSelection002, TestSize.Level1)
1884 {
1885     ASSERT_NE(richEditorNode_, nullptr);
1886     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1887     ASSERT_NE(richEditorPattern, nullptr);
1888     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1889     richEditorPattern->paragraphs_.paragraphs_.push_front({ paragraph });
1890     richEditorPattern->textForDisplay_ = "test";
1891     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
1892     richEditorPattern->spans_.front()->position = 3;
1893     richEditorPattern->InitSelection(Offset(0, 1));
1894     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
1895     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 0);
1896 }
1897 
1898 /**
1899  * @tc.name: CalcInsertValueObj001
1900  * @tc.desc: test CalcInsertValueObj
1901  * @tc.type: FUNC
1902  */
1903 HWTEST_F(RichEditorTestNg, CalcInsertValueObj001, TestSize.Level1)
1904 {
1905     ASSERT_NE(richEditorNode_, nullptr);
1906     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1907     ASSERT_NE(richEditorPattern, nullptr);
1908     AddSpan("test1");
1909     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
1910     auto it = richEditorPattern->spans_.front();
1911     TextInsertValueInfo info;
1912 
1913     it->content = "test";
1914     it->position = 4;
1915     richEditorPattern->caretPosition_ = 0;
1916     richEditorPattern->moveLength_ = 2;
1917 
1918     richEditorPattern->CalcInsertValueObj(info);
1919     EXPECT_EQ(info.spanIndex_, 0);
1920 
1921     richEditorPattern->moveLength_ = -1;
1922     richEditorPattern->CalcInsertValueObj(info);
1923     EXPECT_EQ(info.spanIndex_, 2);
1924 
1925     richEditorPattern->moveLength_ = 5;
1926     richEditorPattern->CalcInsertValueObj(info);
1927     EXPECT_EQ(info.spanIndex_, 2);
1928 }
1929 
1930 /**
1931  * @tc.name: CalcDeleteValueObj001
1932  * @tc.desc: test CalcDeleteValueObj
1933  * @tc.type: FUNC
1934  */
1935 HWTEST_F(RichEditorTestNg, CalcDeleteValueObj001, TestSize.Level1)
1936 {
1937     ASSERT_NE(richEditorNode_, nullptr);
1938     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1939     ASSERT_NE(richEditorPattern, nullptr);
1940     AddSpan("test1");
1941     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
1942     auto it = richEditorPattern->spans_.front();
1943     RichEditorDeleteValue delValue;
1944 
1945     it->content = "test";
1946     it->position = 4;
1947     richEditorPattern->caretPosition_ = 0;
1948     richEditorPattern->moveLength_ = 2;
1949 
1950     richEditorPattern->CalcDeleteValueObj(2, 1, delValue);
1951     EXPECT_EQ(delValue.richEditorDeleteSpans_.size(), 1);
1952 
1953     richEditorPattern->CalcDeleteValueObj(-1, 1, delValue);
1954     EXPECT_EQ(delValue.richEditorDeleteSpans_.size(), 1);
1955 
1956     richEditorPattern->CalcDeleteValueObj(5, 1, delValue);
1957     EXPECT_EQ(delValue.richEditorDeleteSpans_.size(), 1);
1958 }
1959 
1960 /**
1961  * @tc.name: MouseRightFocus001
1962  * @tc.desc: test MouseRightFocus
1963  * @tc.type: FUNC
1964  */
1965 HWTEST_F(RichEditorTestNg, MouseRightFocus001, TestSize.Level1)
1966 {
1967     ASSERT_NE(richEditorNode_, nullptr);
1968     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1969     ASSERT_NE(richEditorPattern, nullptr);
1970     AddSpan("test1");
1971     AddImageSpan();
1972     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
1973     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
1974     auto it = richEditorPattern->spans_.front();
1975     it->content = "test";
1976     it->position = 4;
1977     richEditorPattern->caretPosition_ = richEditorPattern->GetTextContentLength();
1978     richEditorPattern->moveLength_ = 0;
1979     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1980     richEditorPattern->paragraphs_.paragraphs_.push_front({ paragraph });
1981     MouseInfo info;
1982     richEditorPattern->textSelector_.baseOffset = 0;
1983     richEditorPattern->textSelector_.destinationOffset = 0;
1984     richEditorPattern->MouseRightFocus(info);
1985     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
1986 
1987     richEditorPattern->textSelector_.baseOffset = 0;
1988     richEditorPattern->textSelector_.destinationOffset = 1;
1989     richEditorPattern->MouseRightFocus(info);
1990     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
1991 }
1992 
1993 /**
1994  * @tc.name: HandleMouseEvent002
1995  * @tc.desc: test handle mouse event
1996  * @tc.type: FUNC
1997  */
1998 HWTEST_F(RichEditorTestNg, HandleMouseEvent002, TestSize.Level1)
1999 {
2000     ASSERT_NE(richEditorNode_, nullptr);
2001     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2002     ASSERT_NE(richEditorPattern, nullptr);
2003     MouseInfo info;
2004     info.button_ = MouseButton::RIGHT_BUTTON;
2005     info.action_ = MouseAction::RELEASE;
2006     richEditorPattern->HandleMouseEvent(info);
2007     info.action_ = MouseAction::PRESS;
2008     richEditorPattern->HandleMouseEvent(info);
2009     EXPECT_TRUE(richEditorPattern->isMousePressed_);
2010     info.button_ = MouseButton::LEFT_BUTTON;
2011     info.action_ = MouseAction::MOVE;
2012     richEditorPattern->leftMousePress_ = true;
2013     richEditorPattern->HandleMouseEvent(info);
2014     info.action_ = MouseAction::PRESS;
2015     richEditorPattern->HandleMouseEvent(info);
2016     info.action_ = MouseAction::RELEASE;
2017     EXPECT_TRUE(richEditorPattern->isMousePressed_);
2018     richEditorPattern->HandleMouseEvent(info);
2019     EXPECT_FALSE(richEditorPattern->blockPress_);
2020     EXPECT_FALSE(richEditorPattern->leftMousePress_);
2021     EXPECT_FALSE(richEditorPattern->isMouseSelect_);
2022     EXPECT_FALSE(richEditorPattern->isMousePressed_);
2023     EXPECT_TRUE(richEditorPattern->isFirstMouseSelect_);
2024 }
2025 
2026 /**
2027  * @tc.name: OnHover001
2028  * @tc.desc: test on hover
2029  * @tc.type: FUNC
2030  */
2031 HWTEST_F(RichEditorTestNg, OnHover001, TestSize.Level1)
2032 {
2033     ASSERT_NE(richEditorNode_, nullptr);
2034     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2035     ASSERT_NE(richEditorPattern, nullptr);
2036     auto host = richEditorPattern->GetHost();
2037     ASSERT_NE(host, nullptr);
2038     auto id = host->GetId();
2039     auto pipeline = PipelineContext::GetCurrentContext();
2040     ASSERT_NE(pipeline, nullptr);
2041     richEditorPattern->OnHover(true);
2042     EXPECT_EQ(pipeline->mouseStyleNodeId_, id);
2043     richEditorPattern->OnHover(false);
2044     EXPECT_EQ(pipeline->mouseStyleNodeId_, -1);
2045 }
2046 
2047 /**
2048  * @tc.name: OnHandleMove001
2049  * @tc.desc: test on handle move
2050  * @tc.type: FUNC
2051  */
2052 HWTEST_F(RichEditorTestNg, OnHandleMove001, TestSize.Level1)
2053 {
2054     ASSERT_NE(richEditorNode_, nullptr);
2055     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2056     ASSERT_NE(richEditorPattern, nullptr);
2057     richEditorPattern->caretPosition_ = -1;
2058     richEditorPattern->selectOverlay_->OnHandleMove(RectF(0.0f, 0.0f, 10.0f, 10.0f), true);
2059     EXPECT_EQ(richEditorPattern->caretPosition_, -1);
2060 
2061     richEditorPattern->caretPosition_ = -1;
2062     richEditorPattern->selectOverlay_->OnHandleMove(RectF(0.0f, 0.0f, 10.0f, 10.0f), false);
2063     EXPECT_EQ(richEditorPattern->caretPosition_, -1);
2064 }
2065 
2066 /**
2067  * @tc.name: OnAreaChangedInner001
2068  * @tc.desc: test OnAreaChangedInner
2069  * @tc.type: FUNC
2070  */
2071 HWTEST_F(RichEditorTestNg, OnAreaChangedInner001, TestSize.Level1)
2072 {
2073     ASSERT_NE(richEditorNode_, nullptr);
2074     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2075     ASSERT_NE(richEditorPattern, nullptr);
2076     richEditorPattern->OnAreaChangedInner();
2077     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
2078     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
2079     richEditorPattern->parentGlobalOffset_ = OffsetF(0, 1);
2080 
2081     richEditorPattern->OnAreaChangedInner();
2082     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
2083     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
2084 }
2085 
2086 /**
2087  * @tc.name: OnHandleMoveDone001
2088  * @tc.desc: test on handle move done
2089  * @tc.type: FUNC
2090  */
2091 HWTEST_F(RichEditorTestNg, OnHandleMoveDone001, TestSize.Level1)
2092 {
2093     ASSERT_NE(richEditorNode_, nullptr);
2094     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2095     ASSERT_NE(richEditorPattern, nullptr);
__anon814dfc0d1102(const BaseEventInfo* info) 2096     auto func = [](const BaseEventInfo* info) { testOnSelect = 1; };
2097     auto eventHub = richEditorNode_->GetEventHub<RichEditorEventHub>();
2098     ASSERT_NE(eventHub, nullptr);
2099     eventHub->onSelect_ = std::move(func);
2100     richEditorPattern->OnHandleMoveDone(RectF(0.0f, 0.0f, 10.0f, 10.0f), true);
2101     EXPECT_EQ(testOnSelect, 1);
2102 }
2103 
2104 /**
2105  * @tc.name: GetSelectedSpanText002
2106  * @tc.desc: test get select span text
2107  * @tc.type: FUNC
2108  */
2109 HWTEST_F(RichEditorTestNg, GetSelectedSpanText002, TestSize.Level1)
2110 {
2111     ASSERT_NE(richEditorNode_, nullptr);
2112     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2113     ASSERT_NE(richEditorPattern, nullptr);
2114 
2115     auto ret = richEditorPattern->GetSelectedSpanText(StringUtils::ToWstring(INIT_VALUE_1), -1, 1);
2116     ret = richEditorPattern->GetSelectedSpanText(StringUtils::ToWstring(INIT_VALUE_1), -1, 10);
2117     ret = richEditorPattern->GetSelectedSpanText(StringUtils::ToWstring(INIT_VALUE_1), 0, 1);
2118     EXPECT_EQ(ret, "h");
2119 }
2120 
2121 /**
2122  * @tc.name: GetChildByIndex002
2123  * @tc.desc: test get child by index
2124  * @tc.type: FUNC
2125  */
2126 HWTEST_F(RichEditorTestNg, GetChildByIndex002, TestSize.Level1)
2127 {
2128     ASSERT_NE(richEditorNode_, nullptr);
2129     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2130     ASSERT_NE(richEditorPattern, nullptr);
2131     richEditorPattern->GetChildByIndex(-1);
2132     AddSpan(INIT_VALUE_1);
2133     auto ret = richEditorPattern->GetChildByIndex(0);
2134     EXPECT_EQ(*(richEditorNode_->GetChildren().begin()), ret);
2135 }
2136 
2137 /**
2138  * @tc.name: HandleMouseEvent001
2139  * @tc.desc: test HandleMouseEvent
2140  * @tc.type: FUNC
2141  */
2142 HWTEST_F(RichEditorTestNg, HandleMouseEvent001, TestSize.Level1)
2143 {
2144     ASSERT_NE(richEditorNode_, nullptr);
2145     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2146     MouseInfo mouseInfo;
2147 
2148     mouseInfo.action_ = MouseAction::PRESS;
2149     mouseInfo.button_ = MouseButton::LEFT_BUTTON;
2150     richEditorPattern->isMousePressed_ = false;
2151     richEditorPattern->HandleMouseEvent(mouseInfo);
2152     EXPECT_TRUE(richEditorPattern->isMousePressed_);
2153 
2154     mouseInfo.button_ = MouseButton::RIGHT_BUTTON;
2155     richEditorPattern->isMousePressed_ = false;
2156     richEditorPattern->HandleMouseEvent(mouseInfo);
2157     EXPECT_TRUE(richEditorPattern->isMousePressed_);
2158 
2159     mouseInfo.button_ = MouseButton::BACK_BUTTON;
2160     richEditorPattern->isMousePressed_ = false;
2161     richEditorPattern->HandleMouseEvent(mouseInfo);
2162     EXPECT_FALSE(richEditorPattern->isMousePressed_);
2163 }
2164 
2165 /**
2166  * @tc.name: GetChildByIndex001
2167  * @tc.desc: test GetChildByIndex
2168  * @tc.type: FUNC
2169  */
2170 HWTEST_F(RichEditorTestNg, GetChildByIndex001, TestSize.Level1)
2171 {
2172     ASSERT_NE(richEditorNode_, nullptr);
2173     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2174     ASSERT_NE(richEditorPattern, nullptr);
2175     richEditorPattern->caretPosition_ = 0;
2176     AddSpan(INIT_VALUE_1);
2177     auto ret1 = richEditorPattern->GetChildByIndex(1);
2178     EXPECT_EQ(ret1, nullptr);
2179     auto ret2 = richEditorPattern->GetChildByIndex(-1);
2180     EXPECT_EQ(ret2, nullptr);
2181     auto ret3 = richEditorPattern->GetChildByIndex(0);
2182     EXPECT_NE(ret3, nullptr);
2183 }
2184 
2185 /**
2186  * @tc.name: GetSelectedSpanText001
2187  * @tc.desc: test GetSelectedSpanText
2188  * @tc.type: FUNC
2189  */
2190 HWTEST_F(RichEditorTestNg, GetSelectedSpanText001, TestSize.Level1)
2191 {
2192     ASSERT_NE(richEditorNode_, nullptr);
2193     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2194     ASSERT_NE(richEditorPattern, nullptr);
2195     std::string ori = "12345";
2196     std::wstring value = StringUtils::ToWstring(ori);
2197 
2198     std::vector<int> start = { -1, 0, 15 };
2199     std::vector<int> end = { 10, -3 };
2200 
2201     for (int i = 0; i < 3; ++i) {
2202         for (int j = 0; j < 2; ++j) {
2203             auto ret = richEditorPattern->GetSelectedSpanText(value, start[i], end[j]);
2204             EXPECT_EQ(ret, "");
2205         }
2206     }
2207 
2208     auto ret = richEditorPattern->GetSelectedSpanText(value, 0, 1);
2209     EXPECT_EQ(ret, "1");
2210 }
2211 
2212 /**
2213  * @tc.name: HandleSurfaceChanged001
2214  * @tc.desc: test HandleSurfaceChanged
2215  * @tc.type: FUNC
2216  */
2217 HWTEST_F(RichEditorTestNg, HandleSurfaceChanged001, TestSize.Level1)
2218 {
2219     ASSERT_NE(richEditorNode_, nullptr);
2220     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2221     ASSERT_NE(richEditorPattern, nullptr);
2222     std::vector<std::vector<int>> cases = { { 1, 1, 2, 2 }, { 1, 2, 2, 2 }, { 1, 1, 1, 2 }, { 1, 2, 1, 2 } };
2223     for (uint32_t i = 0; i < cases.size(); ++i) {
2224         richEditorPattern->HandleSurfaceChanged(cases[i][0], cases[i][1], cases[i][2], cases[i][3]);
2225         EXPECT_NE(richEditorPattern, nullptr);
2226     }
2227 }
2228 
2229 /**
2230  * @tc.name: CopySelectionMenuParams001
2231  * @tc.desc: test CopySelectionMenuParams
2232  * @tc.type: FUNC
2233  */
2234 HWTEST_F(RichEditorTestNg, CopySelectionMenuParams001, TestSize.Level1)
2235 {
2236     ASSERT_NE(richEditorNode_, nullptr);
2237     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2238     ASSERT_NE(richEditorPattern, nullptr);
2239     SelectOverlayInfo selectInfo;
2240     richEditorPattern->selectedType_ = TextSpanType::TEXT;
2241     richEditorPattern->CopySelectionMenuParams(selectInfo, TextResponseType::LONG_PRESS);
2242     EXPECT_EQ(selectInfo.menuCallback.onDisappear, nullptr);
2243 
2244     richEditorPattern->selectedType_ = TextSpanType::IMAGE;
2245     richEditorPattern->CopySelectionMenuParams(selectInfo, TextResponseType::LONG_PRESS);
2246     EXPECT_EQ(selectInfo.menuCallback.onDisappear, nullptr);
2247 
2248     richEditorPattern->selectedType_ = TextSpanType::MIXED;
2249     richEditorPattern->CopySelectionMenuParams(selectInfo, TextResponseType::LONG_PRESS);
2250     EXPECT_EQ(selectInfo.menuCallback.onDisappear, nullptr);
2251 
2252     richEditorPattern->selectedType_ = TextSpanType(-1);
2253     richEditorPattern->CopySelectionMenuParams(selectInfo, TextResponseType::LONG_PRESS);
2254     EXPECT_EQ(selectInfo.menuCallback.onDisappear, nullptr);
2255 
2256     auto key = std::make_pair(TextSpanType::MIXED, TextResponseType::RIGHT_CLICK);
2257     callBack1 = 0;
2258     callBack2 = 0;
2259     callBack3 = 0;
__anon814dfc0d1202() 2260     std::function<void()> buildFunc = []() {
2261         callBack1 = 1;
2262         return;
2263     };
__anon814dfc0d1302(int32_t a, int32_t b) 2264     std::function<void(int32_t, int32_t)> onAppear = [](int32_t a, int32_t b) {
2265         callBack2 = 2;
2266         return;
2267     };
__anon814dfc0d1402() 2268     std::function<void()> onDisappear = []() {
2269         callBack3 = 3;
2270         return;
2271     };
2272     std::shared_ptr<SelectionMenuParams> params1 = std::make_shared<SelectionMenuParams>(
2273         TextSpanType::MIXED, buildFunc, onAppear, onDisappear, TextResponseType::RIGHT_CLICK);
2274     richEditorPattern->selectionMenuMap_[key] = params1;
2275     selectInfo.isUsingMouse = true;
2276     richEditorPattern->selectedType_ = TextSpanType::MIXED;
2277     richEditorPattern->CopySelectionMenuParams(selectInfo, TextResponseType::RIGHT_CLICK);
2278     EXPECT_NE(selectInfo.menuCallback.onDisappear, nullptr);
2279 
2280     key = std::make_pair(TextSpanType::MIXED, TextResponseType::LONG_PRESS);
2281     std::shared_ptr<SelectionMenuParams> params2 = std::make_shared<SelectionMenuParams>(
2282         TextSpanType::MIXED, buildFunc, nullptr, nullptr, TextResponseType::RIGHT_CLICK);
2283     richEditorPattern->selectionMenuMap_[key] = params2;
2284     selectInfo.isUsingMouse = false;
2285     richEditorPattern->selectedType_ = TextSpanType::MIXED;
2286     richEditorPattern->CopySelectionMenuParams(selectInfo, TextResponseType::RIGHT_CLICK);
2287     EXPECT_NE(selectInfo.menuCallback.onDisappear, nullptr);
2288 }
2289 
2290 /**
2291  * @tc.name: UpdateSelectionType001
2292  * @tc.desc: test UpdateSelectionType
2293  * @tc.type: FUNC
2294  */
2295 HWTEST_F(RichEditorTestNg, UpdateSelectionType001, TestSize.Level1)
2296 {
2297     ASSERT_NE(richEditorNode_, nullptr);
2298     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2299     ASSERT_NE(richEditorPattern, nullptr);
2300     SelectionInfo selection;
2301 
2302     ResultObject obj1;
2303     obj1.type = SelectSpanType::TYPESPAN;
2304     selection.selection_.resultObjects.push_front(obj1);
2305     richEditorPattern->UpdateSelectionType(selection);
2306     EXPECT_EQ(richEditorPattern->selectedType_.value(), TextSpanType::TEXT);
2307 
2308     selection.selection_.resultObjects.pop_front();
2309     ResultObject obj2;
2310     obj2.type = SelectSpanType::TYPEIMAGE;
2311     selection.selection_.resultObjects.push_front(obj2);
2312     richEditorPattern->UpdateSelectionType(selection);
2313     EXPECT_EQ(richEditorPattern->selectedType_.value(), TextSpanType::IMAGE);
2314 
2315     selection.selection_.resultObjects.push_front(obj1);
2316     richEditorPattern->UpdateSelectionType(selection);
2317     EXPECT_EQ(richEditorPattern->selectedType_.value(), TextSpanType::MIXED);
2318 }
2319 
2320 /**
2321  * @tc.name: CreateNodePaintMethod001
2322  * @tc.desc: test CreateNodePaintMethod
2323  * @tc.type: FUNC
2324  */
2325 HWTEST_F(RichEditorTestNg, CreateNodePaintMethod001, TestSize.Level1)
2326 {
2327     ASSERT_NE(richEditorNode_, nullptr);
2328     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2329     ASSERT_NE(richEditorPattern, nullptr);
2330     richEditorPattern->CreateNodePaintMethod();
2331     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
2332     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
2333 }
2334 
2335 /**
2336  * @tc.name: CreateNodePaintMethod002
2337  * @tc.desc: test CreateNodePaintMethod
2338  * @tc.type: FUNC
2339  */
2340 HWTEST_F(RichEditorTestNg, CreateNodePaintMethod002, TestSize.Level1)
2341 {
2342     ASSERT_NE(richEditorNode_, nullptr);
2343     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2344     ASSERT_NE(richEditorPattern, nullptr);
2345     richEditorPattern->contentMod_ = AceType::MakeRefPtr<RichEditorContentModifier>(
2346         richEditorPattern->textStyle_, &richEditorPattern->paragraphs_, richEditorPattern);
2347     richEditorPattern->isCustomFont_ = true;
2348     richEditorPattern->CreateNodePaintMethod();
2349     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
2350     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
2351 }
2352 
2353 /**
2354  * @tc.name: BindSelectionMenu001
2355  * @tc.desc: test BindSelectionMenu
2356  * @tc.type: FUNC
2357  */
2358 HWTEST_F(RichEditorTestNg, BindSelectionMenu001, TestSize.Level1)
2359 {
2360     ASSERT_NE(richEditorNode_, nullptr);
2361     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2362     ASSERT_NE(richEditorPattern, nullptr);
2363     callBack1 = 0;
2364     callBack2 = 0;
2365     callBack3 = 0;
__anon814dfc0d1502() 2366     std::function<void()> buildFunc = []() {
2367         callBack1 = 1;
2368         return;
2369     };
__anon814dfc0d1602(int32_t a, int32_t b) 2370     std::function<void(int32_t, int32_t)> onAppear = [](int32_t a, int32_t b) {
2371         callBack2 = 2;
2372         return;
2373     };
__anon814dfc0d1702() 2374     std::function<void()> onDisappear = []() {
2375         callBack3 = 3;
2376         return;
2377     };
2378 
2379     auto key = std::make_pair(TextSpanType::MIXED, TextResponseType::RIGHT_CLICK);
2380     std::shared_ptr<SelectionMenuParams> params1 = std::make_shared<SelectionMenuParams>(
2381         TextSpanType::MIXED, buildFunc, onAppear, onDisappear, TextResponseType::RIGHT_CLICK);
2382     richEditorPattern->selectionMenuMap_[key] = params1;
2383 
2384     std::function<void()> nullFunc = nullptr;
2385 
2386     richEditorPattern->BindSelectionMenu(
2387         TextResponseType::RIGHT_CLICK, TextSpanType::MIXED, nullFunc, onAppear, onDisappear);
2388     EXPECT_TRUE(richEditorPattern->selectionMenuMap_.empty());
2389 
2390     richEditorPattern->selectionMenuMap_[key] = params1;
2391     richEditorPattern->BindSelectionMenu(
2392         TextResponseType::RIGHT_CLICK, TextSpanType::MIXED, buildFunc, onAppear, onDisappear);
2393     EXPECT_FALSE(richEditorPattern->selectionMenuMap_.empty());
2394 
2395     richEditorPattern->BindSelectionMenu(
2396         TextResponseType::RIGHT_CLICK, TextSpanType::IMAGE, buildFunc, onAppear, onDisappear);
2397     EXPECT_FALSE(richEditorPattern->selectionMenuMap_.empty());
2398 }
2399 
2400 /**
2401  * @tc.name: HandleMouseLeftButton002
2402  * @tc.desc: test HandleMouseLeftButton
2403  * @tc.type: FUNC
2404  */
2405 HWTEST_F(RichEditorTestNg, HandleMouseLeftButton002, TestSize.Level1)
2406 {
2407     ASSERT_NE(richEditorNode_, nullptr);
2408     AddSpan(INIT_VALUE_1);
2409     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2410     ASSERT_NE(richEditorPattern, nullptr);
2411     MouseInfo mouseInfo;
2412     mouseInfo.action_ = MouseAction::RELEASE;
2413     mouseInfo.SetGlobalLocation(MOUSE_GLOBAL_LOCATION);
2414     richEditorPattern->mouseStatus_ = MouseStatus::NONE;
2415     richEditorPattern->HandleMouseLeftButton(mouseInfo);
2416     EXPECT_EQ(richEditorPattern->mouseStatus_, MouseStatus::RELEASED);
2417     richEditorPattern->textSelector_ = TextSelector(0, 2);
2418     std::vector<TextSpanType> selectType = { TextSpanType::TEXT, TextSpanType::IMAGE, TextSpanType::MIXED };
2419     SelectOverlayInfo selectInfo;
2420     selectInfo.isUsingMouse = true;
2421     for (size_t i = 0; i < selectType.size(); i++) {
2422         richEditorPattern->selectedType_ = selectType[i];
2423         richEditorPattern->HandleMouseLeftButton(mouseInfo);
2424         EXPECT_NE(richEditorPattern->selectionMenuOffsetByMouse_.GetX(),
2425             static_cast<float>(mouseInfo.GetGlobalLocation().GetX()));
2426         EXPECT_NE(richEditorPattern->selectionMenuOffsetByMouse_.GetY(),
2427             static_cast<float>(mouseInfo.GetGlobalLocation().GetY()));
2428     }
__anon814dfc0d1802() 2429     std::function<void()> buildFunc = []() {
2430         callBack1 = 1;
2431         return;
2432     };
__anon814dfc0d1902(int32_t a, int32_t b) 2433     std::function<void(int32_t, int32_t)> onAppear = [](int32_t a, int32_t b) {
2434         callBack2 = 2;
2435         return;
2436     };
__anon814dfc0d1a02() 2437     std::function<void()> onDisappear = []() {
2438         callBack3 = 3;
2439         return;
2440     };
2441     richEditorPattern->mouseStatus_ = MouseStatus::MOVE;
2442     for (size_t i = 0; i < selectType.size(); i++) {
2443         richEditorPattern->selectedType_ = selectType[i];
2444         auto key = std::make_pair(selectType[i], TextResponseType::SELECTED_BY_MOUSE);
2445         std::shared_ptr<SelectionMenuParams> params1 = std::make_shared<SelectionMenuParams>(
2446             selectType[i], buildFunc, onAppear, onDisappear, TextResponseType::SELECTED_BY_MOUSE);
2447         richEditorPattern->selectionMenuMap_[key] = params1;
2448         richEditorPattern->HandleMouseLeftButton(mouseInfo);
2449         EXPECT_EQ(richEditorPattern->selectionMenuOffsetByMouse_.GetX(),
2450             static_cast<float>(mouseInfo.GetGlobalLocation().GetX()));
2451         EXPECT_EQ(richEditorPattern->selectionMenuOffsetByMouse_.GetY(),
2452             static_cast<float>(mouseInfo.GetGlobalLocation().GetY()));
2453     }
2454 }
2455 
2456 /**
2457  * @tc.name: Selection001
2458  * @tc.desc: test SetSelection and GetSelection
2459  * @tc.type: FUNC
2460  */
2461 HWTEST_F(RichEditorTestNg, Selection001, TestSize.Level1)
2462 {
2463     ASSERT_NE(richEditorNode_, nullptr);
2464     AddSpan(INIT_VALUE_1);
2465     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2466     ASSERT_NE(richEditorPattern, nullptr);
2467     auto richEditorController = richEditorPattern->GetRichEditorController();
2468     ASSERT_NE(richEditorController, nullptr);
2469     richEditorPattern->SetSelection(0, 1);
2470     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
2471     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
2472     auto richEditorSelection = richEditorController->GetSelectionSpansInfo().GetSelection();
2473     EXPECT_EQ(richEditorSelection.selection[0], 0);
2474     EXPECT_EQ(richEditorSelection.selection[1], 0);
2475 
2476     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2477     ASSERT_NE(focusHub, nullptr);
2478     focusHub->RequestFocusImmediately();
2479     richEditorPattern->SetSelection(0, 1);
2480     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2481     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 1);
2482     EXPECT_EQ(richEditorPattern->caretPosition_, 1);
2483     auto richEditorSelection2 = richEditorController->GetSelectionSpansInfo().GetSelection();
2484     EXPECT_EQ(richEditorSelection2.selection[0], 0);
2485     EXPECT_EQ(richEditorSelection2.selection[1], 1);
2486 
2487     richEditorPattern->SetSelection(3, 1);
2488     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
2489     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
2490     EXPECT_EQ(richEditorPattern->caretPosition_, 1);
2491     auto richEditorSelection3 = richEditorController->GetSelectionSpansInfo().GetSelection();
2492     EXPECT_EQ(richEditorSelection3.selection[0], 1);
2493     EXPECT_EQ(richEditorSelection3.selection[1], 1);
2494 
2495     richEditorPattern->SetSelection(-1, -1);
2496     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2497     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 6);
2498     EXPECT_EQ(richEditorPattern->caretPosition_, 6);
2499     auto richEditorSelection4 = richEditorController->GetSelectionSpansInfo().GetSelection();
2500     EXPECT_EQ(richEditorSelection4.selection[0], 0);
2501     EXPECT_EQ(richEditorSelection4.selection[1], 6);
2502 
2503     richEditorPattern->SetSelection(0, 10);
2504     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2505     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 6);
2506     EXPECT_EQ(richEditorPattern->caretPosition_, 6);
2507     auto richEditorSelection5 = richEditorController->GetSelectionSpansInfo().GetSelection();
2508     EXPECT_EQ(richEditorSelection5.selection[0], 0);
2509     EXPECT_EQ(richEditorSelection5.selection[1], 6);
2510 
2511     richEditorPattern->SetSelection(-2, 3);
2512     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2513     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 3);
2514     EXPECT_EQ(richEditorPattern->caretPosition_, 3);
2515     auto richEditorSelection6 = richEditorController->GetSelectionSpansInfo().GetSelection();
2516     EXPECT_EQ(richEditorSelection6.selection[0], 0);
2517     EXPECT_EQ(richEditorSelection6.selection[1], 3);
2518 
2519     richEditorPattern->SetSelection(-2, 8);
2520     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2521     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 6);
2522     EXPECT_EQ(richEditorPattern->caretPosition_, 6);
2523     auto richEditorSelection7 = richEditorController->GetSelectionSpansInfo().GetSelection();
2524     EXPECT_EQ(richEditorSelection7.selection[0], 0);
2525     EXPECT_EQ(richEditorSelection7.selection[1], 6);
2526 
2527     richEditorPattern->SetSelection(-2, -1);
2528     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
2529     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
2530     EXPECT_EQ(richEditorPattern->caretPosition_, 6);
2531     auto richEditorSelection8 = richEditorController->GetSelectionSpansInfo().GetSelection();
2532     EXPECT_EQ(richEditorSelection8.selection[0], 6);
2533     EXPECT_EQ(richEditorSelection8.selection[1], 6);
2534 
2535     richEditorPattern->SetSelection(1, 3);
2536     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 1);
2537     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 3);
2538     EXPECT_EQ(richEditorPattern->caretPosition_, 3);
2539     auto richEditorSelection9 = richEditorController->GetSelectionSpansInfo().GetSelection();
2540     EXPECT_EQ(richEditorSelection9.selection[0], 1);
2541     EXPECT_EQ(richEditorSelection9.selection[1], 3);
2542 }
2543 
2544 /**
2545  * @tc.name: SetSelection002
2546  * @tc.desc: test SetSelection and GetSelection
2547  * @tc.type: FUNC
2548  */
2549 HWTEST_F(RichEditorTestNg, Selection002, TestSize.Level1)
2550 {
2551     ASSERT_NE(richEditorNode_, nullptr);
2552     AddSpan(INIT_VALUE_1);
2553     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2554     ASSERT_NE(richEditorPattern, nullptr);
2555     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2556     ASSERT_NE(focusHub, nullptr);
2557     focusHub->RequestFocusImmediately();
2558     richEditorPattern->SetSelection(0, 1);
2559     auto richEditorController = richEditorPattern->GetRichEditorController();
2560     ASSERT_NE(richEditorController, nullptr);
2561     /**
2562      * @tc.step: step1. Empty text calls the setSelection interface.
2563      * @tc.expected: The interface exits normally, but it does not take effect
2564      */
2565     ClearSpan();
2566     richEditorPattern->SetSelection(1, 3);
2567     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
2568     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
2569     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
2570     auto richEditorSelection = richEditorController->GetSelectionSpansInfo().GetSelection();
2571     EXPECT_EQ(richEditorSelection.selection[0], 0);
2572     EXPECT_EQ(richEditorSelection.selection[1], 0);
2573     /**
2574      * @tc.step: step2. Extra-long text scenes.
2575      * @tc.expected: A portion of the selected text is not displayed, but the selection range can be updated
2576      * successfully
2577      */
2578     AddSpan(INIT_VALUE_3);
2579     SizeF sizeF(10.0f, 10.0f);
2580     richEditorNode_->GetGeometryNode()->SetContentSize(sizeF);
2581     richEditorPattern->SetSelection(15, 30);
2582     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 15);
2583     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 30);
2584     EXPECT_EQ(richEditorPattern->caretPosition_, 30);
2585     auto richEditorSelection2 = richEditorController->GetSelectionSpansInfo().GetSelection();
2586     EXPECT_EQ(richEditorSelection2.selection[0], 15);
2587     EXPECT_EQ(richEditorSelection2.selection[1], 30);
2588     auto resultObject = richEditorSelection2.resultObjects.front();
2589     EXPECT_EQ(resultObject.valueString, INIT_VALUE_3);
2590     EXPECT_EQ(resultObject.offsetInSpan[0], 15);
2591     EXPECT_EQ(resultObject.offsetInSpan[1], 30);
2592 }
2593 
2594 /**
2595  * @tc.name: Selection003
2596  * @tc.desc: test SetSelection
2597  * @tc.type: FUNC
2598  */
2599 HWTEST_F(RichEditorTestNg, Selection003, TestSize.Level1)
2600 {
2601     /**
2602      * @tc.step: step1. Add text span and get richeditor pattern.
2603      */
2604     AddSpan(INIT_VALUE_1);
2605     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2606     ASSERT_NE(richEditorPattern, nullptr);
2607 
2608     /**
2609      * @tc.step: step2. Request focus.
2610      */
2611     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2612     focusHub->RequestFocusImmediately();
2613 
2614     /**
2615      * @tc.step: step3. Call SetSelection with no menu
2616      * @tc.expected: Text is selected and the menu doesn't pop up
2617      */
2618     int32_t start = 0;
2619     int32_t end = 1;
2620     SelectionOptions options;
2621     options.menuPolicy = MenuPolicy::DEFAULT;
2622     richEditorPattern->OnModifyDone();
2623     richEditorPattern->SetSelection(start, end, options);
2624 
2625     /**
2626      * @tc.step: step4. Call SetSelection with forward selection
2627      * @tc.expected: Cursor at start position
2628      */
2629     richEditorPattern->SetSelection(start, end, options, true);
2630     EXPECT_EQ(richEditorPattern->GetCaretPosition(), start);
2631 
2632     /**
2633      * @tc.step: step5. Call SetSelection with backward selection
2634      * @tc.expected: Cursor at end position
2635      */
2636     richEditorPattern->SetSelection(start, end, options, false);
2637     EXPECT_EQ(richEditorPattern->GetCaretPosition(), end);
2638 
2639     ClearSpan();
2640     EXPECT_FALSE(richEditorPattern->SelectOverlayIsOn());
2641     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, start);
2642     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, end);
2643 }
2644 
2645 /**
2646  * @tc.name: Selection004
2647  * @tc.desc: test SetSelection
2648  * @tc.type: FUNC
2649  */
2650 HWTEST_F(RichEditorTestNg, Selection004, TestSize.Level1)
2651 {
2652     /**
2653      * @tc.step: step1. Add text span and get richeditor pattern.
2654      */
2655     AddSpan(INIT_VALUE_1);
2656     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2657     ASSERT_NE(richEditorPattern, nullptr);
2658 
2659     /**
2660      * @tc.step: step2. Request focus.
2661      */
2662     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2663     focusHub->RequestFocusImmediately();
2664 
2665     /**
2666      * @tc.step: step3. Create a scene where the text menu has popped up.
2667      */
2668     richEditorPattern->OnModifyDone();
2669     richEditorPattern->textSelector_.Update(0, 1);
2670     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
2671     richEditorPattern->ShowSelectOverlay(
2672         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
2673     EXPECT_TRUE(richEditorPattern->SelectOverlayIsOn());
2674 
2675     /**
2676      * @tc.step: step4. Call SetSelection with menu pop up
2677      * @tc.expected: Text is selected and the menu still pop up
2678      */
2679     int32_t start = -1;
2680     int32_t end = -1;
2681     SelectionOptions options;
2682     options.menuPolicy = MenuPolicy::DEFAULT;
2683     richEditorPattern->SetSelection(start, end, options);
2684 
2685     /**
2686      * @tc.step: step5. Call SetSelection with forward selection
2687      * @tc.expected: Cursor at start position
2688      */
2689     richEditorPattern->SetSelection(start, end, options, true);
2690     EXPECT_EQ(richEditorPattern->GetCaretPosition(), 0);
2691 
2692     /**
2693      * @tc.step: step6. Call SetSelection with backward selection
2694      * @tc.expected: Cursor at end position
2695      */
2696     richEditorPattern->SetSelection(start, end, options, false);
2697     EXPECT_EQ(richEditorPattern->GetCaretPosition(), INIT_VALUE_1.length());
2698 
2699     ClearSpan();
2700     EXPECT_FALSE(richEditorPattern->SelectOverlayIsOn());
2701     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2702     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, INIT_VALUE_1.length());
2703 }
2704 
2705 /**
2706  * @tc.name: Selection005
2707  * @tc.desc: test SetSelection
2708  * @tc.type: FUNC
2709  */
2710 HWTEST_F(RichEditorTestNg, Selection005, TestSize.Level1)
2711 {
2712     /**
2713      * @tc.step: step1. Add text span and get richeditor pattern.
2714      */
2715     AddSpan(INIT_VALUE_1);
2716     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2717     ASSERT_NE(richEditorPattern, nullptr);
2718 
2719     /**
2720      * @tc.step: step2. Request focus.
2721      */
2722     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2723     focusHub->RequestFocusImmediately();
2724 
2725     /**
2726      * @tc.step: step3. Call SetSelection with no menu
2727      * @tc.expected: Text is selected and the menu doesn't pop up
2728      */
2729     int32_t start = 0;
2730     int32_t end = 1;
2731     SelectionOptions options;
2732     options.menuPolicy = MenuPolicy::HIDE;
2733     richEditorPattern->OnModifyDone();
2734     richEditorPattern->SetSelection(start, end, options);
2735     ClearSpan();
2736     EXPECT_FALSE(richEditorPattern->SelectOverlayIsOn());
2737     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, start);
2738     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, end);
2739 }
2740 
2741 /**
2742  * @tc.name: Selection006
2743  * @tc.desc: test SetSelection
2744  * @tc.type: FUNC
2745  */
2746 HWTEST_F(RichEditorTestNg, Selection006, TestSize.Level1)
2747 {
2748     /**
2749      * @tc.step: step1. Add text span and get richeditor pattern.
2750      */
2751     AddSpan(INIT_VALUE_1);
2752     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2753     ASSERT_NE(richEditorPattern, nullptr);
2754 
2755     /**
2756      * @tc.step: step2. Request focus.
2757      */
2758     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2759     focusHub->RequestFocusImmediately();
2760 
2761     /**
2762      * @tc.step: step3. Create a scene where the text menu has popped up.
2763      */
2764     richEditorPattern->OnModifyDone();
2765     richEditorPattern->textSelector_.Update(0, 1);
2766     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
2767     richEditorPattern->ShowSelectOverlay(
2768         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
2769     EXPECT_TRUE(richEditorPattern->SelectOverlayIsOn());
2770 
2771     /**
2772      * @tc.step: step4. Call SetSelection with menu pop up.
2773      * @tc.expected: Text is selected and menu doesn't pop up.
2774      */
2775     int32_t start = -1;
2776     int32_t end = -1;
2777     SelectionOptions options;
2778     options.menuPolicy = MenuPolicy::HIDE;
2779     richEditorPattern->SetSelection(start, end, options);
2780     ClearSpan();
2781     EXPECT_FALSE(richEditorPattern->SelectOverlayIsOn());
2782     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2783     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, INIT_VALUE_1.length());
2784 }
2785 
2786 /**
2787  * @tc.name: Selection007
2788  * @tc.desc: test SetSelection
2789  * @tc.type: FUNC
2790  */
2791 HWTEST_F(RichEditorTestNg, Selection007, TestSize.Level1)
2792 {
2793     /**
2794      * @tc.step: step1. Add text span and get richeditor pattern.
2795      */
2796     AddSpan(INIT_VALUE_1);
2797     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2798     ASSERT_NE(richEditorPattern, nullptr);
2799 
2800     /**
2801      * @tc.step: step2. Request focus.
2802      */
2803     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2804     focusHub->RequestFocusImmediately();
2805 
2806     /**
2807      * @tc.step: step3. Call SetSelection with no menu
2808      * @tc.expected: Text is selected and the menu pop up
2809      */
2810     int32_t start = 0;
2811     int32_t end = 1;
2812     SelectionOptions options;
2813     options.menuPolicy = MenuPolicy::SHOW;
2814     richEditorPattern->OnModifyDone();
2815     richEditorPattern->SetSelection(start, end, options);
2816     ClearSpan();
2817     EXPECT_FALSE(richEditorPattern->SelectOverlayIsOn());
2818     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, start);
2819     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, end);
2820 }
2821 
2822 /**
2823  * @tc.name: Selection008
2824  * @tc.desc: test SetSelection
2825  * @tc.type: FUNC
2826  */
2827 HWTEST_F(RichEditorTestNg, Selection008, TestSize.Level1)
2828 {
2829     /**
2830      * @tc.step: step1. Add text span and get richeditor pattern.
2831      */
2832     AddSpan(INIT_VALUE_1);
2833     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2834     ASSERT_NE(richEditorPattern, nullptr);
2835 
2836     /**
2837      * @tc.step: step2. Request focus.
2838      */
2839     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
2840     focusHub->RequestFocusImmediately();
2841 
2842     /**
2843      * @tc.step: step3. Create a scene where the text menu has popped up.
2844      */
2845     richEditorPattern->OnModifyDone();
2846     richEditorPattern->textSelector_.Update(0, 1);
2847     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
2848     richEditorPattern->ShowSelectOverlay(
2849         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
2850     EXPECT_TRUE(richEditorPattern->SelectOverlayIsOn());
2851 
2852     /**
2853      * @tc.step: step4. Call SetSelection with menu pop up.
2854      * @tc.expected: Text is selected and menu pop up.
2855      */
2856     int32_t start = -1;
2857     int32_t end = -1;
2858     SelectionOptions options;
2859     options.menuPolicy = MenuPolicy::SHOW;
2860     richEditorPattern->SetSelection(start, end, options);
2861     ClearSpan();
2862     EXPECT_FALSE(richEditorPattern->SelectOverlayIsOn());
2863     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2864     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, INIT_VALUE_1.length());
2865 }
2866 
2867 /**
2868  * @tc.name: HandleMouseRightButton001
2869  * @tc.desc: test HandleMouseRightButton
2870  * @tc.type: FUNC
2871  */
2872 HWTEST_F(RichEditorTestNg, HandleMouseRightButton001, TestSize.Level1)
2873 {
2874     ASSERT_NE(richEditorNode_, nullptr);
2875     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2876     ClipboardProxy::GetInstance()->SetDelegate(nullptr);
2877 
2878     MouseInfo mouseInfo;
2879     mouseInfo.action_ = MouseAction::PRESS;
2880     richEditorPattern->isMousePressed_ = false;
2881     richEditorPattern->HandleMouseRightButton(mouseInfo);
2882     EXPECT_TRUE(richEditorPattern->isMousePressed_);
2883 
2884     mouseInfo.action_ = MouseAction::HOVER;
2885     richEditorPattern->isMousePressed_ = false;
2886     richEditorPattern->HandleMouseRightButton(mouseInfo);
2887     EXPECT_FALSE(richEditorPattern->isMousePressed_);
2888 
2889     mouseInfo.action_ = MouseAction::RELEASE;
2890     richEditorPattern->isMousePressed_ = true;
2891     mouseInfo.SetGlobalLocation({ 1, 5 });
2892     richEditorPattern->textSelector_.baseOffset = -1;
2893     richEditorPattern->textSelector_.destinationOffset = -1;
2894     richEditorPattern->HandleMouseRightButton(mouseInfo);
2895     EXPECT_FALSE(richEditorPattern->isMousePressed_);
2896 
2897     richEditorPattern->textSelector_.baseOffset = 2;
2898     richEditorPattern->textSelector_.destinationOffset = 3;
2899     richEditorPattern->HandleMouseRightButton(mouseInfo);
2900     EXPECT_FALSE(richEditorPattern->isMousePressed_);
2901 
2902     richEditorPattern->textSelector_.baseOffset = 1;
2903     richEditorPattern->textSelector_.destinationOffset = 9;
2904     richEditorPattern->HandleMouseRightButton(mouseInfo);
2905     EXPECT_FALSE(richEditorPattern->isMousePressed_);
2906 }
2907 
2908 /**
2909  * @tc.name: HandleOnCopy001
2910  * @tc.desc: test HandleOnCopy
2911  * @tc.type: FUNC
2912  */
2913 HWTEST_F(RichEditorTestNg, HandleOnCopy001, TestSize.Level1)
2914 {
2915     ASSERT_NE(richEditorNode_, nullptr);
2916     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2917     ASSERT_NE(richEditorPattern, nullptr);
2918     auto pipeline = MockPipelineContext::GetCurrent();
2919     auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2920     richEditorPattern->clipboard_ = clipboard;
2921     AddSpan("test1");
2922     richEditorPattern->HandleOnCopy();
2923     richEditorPattern->textSelector_.baseOffset = 0;
2924     richEditorPattern->textSelector_.destinationOffset = 1;
2925     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2926     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 1);
2927     richEditorPattern->HandleOnCopy();
2928     ClearSpan();
2929     AddImageSpan();
2930     richEditorPattern->textSelector_.baseOffset = 0;
2931     richEditorPattern->textSelector_.destinationOffset = 1;
2932     richEditorPattern->HandleOnCopy();
2933     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
2934     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 1);
2935 }
2936 
2937 /**
2938  * @tc.name: HasSameTypingStyle001
2939  * @tc.desc: test HasSameTypingStyle
2940  * @tc.type: FUNC
2941  */
2942 HWTEST_F(RichEditorTestNg, HasSameTypingStyle001, TestSize.Level1)
2943 {
2944     ASSERT_NE(richEditorNode_, nullptr);
2945     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2946     ASSERT_NE(richEditorPattern, nullptr);
2947     richEditorPattern->caretPosition_ = 0;
2948     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
2949     auto it = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
2950     auto spanItem = it->GetSpanItem();
2951 
2952     spanItem->textStyle_ = std::nullopt;
2953     richEditorPattern->typingTextStyle_ = std::nullopt;
2954     auto ret = richEditorPattern->HasSameTypingStyle(it);
2955     EXPECT_TRUE(ret);
2956 
2957     spanItem->textStyle_ = TextStyle();
2958     richEditorPattern->typingTextStyle_ = std::nullopt;
2959     ret = richEditorPattern->HasSameTypingStyle(it);
2960     EXPECT_FALSE(ret);
2961 
2962     spanItem->textStyle_ = std::nullopt;
2963     richEditorPattern->typingTextStyle_ = TextStyle();
2964     ret = richEditorPattern->HasSameTypingStyle(it);
2965     EXPECT_FALSE(ret);
2966 
2967     spanItem->textStyle_ = TextStyle();
2968     richEditorPattern->typingTextStyle_ = TextStyle();
2969     ret = richEditorPattern->HasSameTypingStyle(it);
2970     EXPECT_TRUE(ret);
2971 
2972     spanItem->textStyle_.value().fontFamilies_.push_back("test1");
2973     ret = richEditorPattern->HasSameTypingStyle(it);
2974     EXPECT_FALSE(ret);
2975 }
2976 
2977 /**
2978  * @tc.name: GetSpanItemByIndex001
2979  * @tc.desc: test GetSpanItemByIndex
2980  * @tc.type: FUNC
2981  */
2982 HWTEST_F(RichEditorTestNg, GetSpanItemByIndex001, TestSize.Level1)
2983 {
2984     ASSERT_NE(richEditorNode_, nullptr);
2985     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
2986     ASSERT_NE(richEditorPattern, nullptr);
2987     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
2988     auto ret = richEditorPattern->GetSpanItemByIndex(-1);
2989     EXPECT_EQ(ret, nullptr);
2990     ret = richEditorPattern->GetSpanItemByIndex(1);
2991     EXPECT_EQ(ret, nullptr);
2992     ret = richEditorPattern->GetSpanItemByIndex(0);
2993     EXPECT_EQ(ret, richEditorPattern->spans_.front());
2994 }
2995 
2996 /**
2997  * @tc.name: GetParagraphNodes001
2998  * @tc.desc: test get paragraph nodes
2999  * @tc.type: FUNC
3000  */
3001 HWTEST_F(RichEditorTestNg, GetParagraphNodes001, TestSize.Level1)
3002 {
3003     ASSERT_NE(richEditorNode_, nullptr);
3004     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3005     auto nodes = richEditorPattern->GetParagraphNodes(1, 5);
3006     EXPECT_EQ(nodes.size(), 0);
3007     nodes = richEditorPattern->GetParagraphNodes(0, INT_MAX);
3008     EXPECT_EQ(nodes.size(), 0);
3009 
3010     // add multiple paragraphs
3011     AddSpan(INIT_VALUE_1 + "\n"); // length 7
3012     AddImageSpan();               // length 1
3013     AddSpan(INIT_VALUE_2 + "\n"); // length 7
3014     AddSpan(INIT_VALUE_1);        // length 6
3015     AddSpan(INIT_VALUE_2 + "\n");
3016     AddSpan(INIT_VALUE_2);
3017     AddSpan(INIT_VALUE_2 + "\n");
3018     AddSpan(INIT_VALUE_2);
3019     EXPECT_EQ(richEditorNode_->children_.size(), 8);
3020 
3021     nodes = richEditorPattern->GetParagraphNodes(3, 5);
3022     EXPECT_EQ(nodes.size(), 1);
3023     EXPECT_EQ(nodes[0]->GetId(), richEditorNode_->GetChildAtIndex(0)->GetId());
3024 
3025     nodes = richEditorPattern->GetParagraphNodes(0, INT_MAX);
3026     EXPECT_EQ(nodes.size(), 7);
3027 
3028     nodes = richEditorPattern->GetParagraphNodes(10, 15);
3029     EXPECT_EQ(nodes.size(), 1);
3030     EXPECT_EQ(nodes[0]->GetId(), richEditorNode_->GetChildAtIndex(2)->GetId());
3031 
3032     nodes = richEditorPattern->GetParagraphNodes(6, 7);
3033     EXPECT_EQ(nodes.size(), 1);
3034     EXPECT_EQ(nodes[0]->GetId(), richEditorNode_->GetChildAtIndex(0)->GetId());
3035 
3036     // selecting only the placeholder region
3037     nodes = richEditorPattern->GetParagraphNodes(7, 8);
3038     EXPECT_EQ(nodes.size(), 1);
3039     EXPECT_EQ(nodes[0]->GetId(), richEditorNode_->GetChildAtIndex(1)->GetId());
3040 
3041     nodes = richEditorPattern->GetParagraphNodes(2, 20);
3042     EXPECT_EQ(nodes.size(), 4);
3043     EXPECT_EQ(nodes[3]->GetId(), richEditorNode_->GetChildAtIndex(4)->GetId());
3044 
3045     nodes = richEditorPattern->GetParagraphNodes(400, 404);
3046     EXPECT_EQ(nodes.size(), 0);
3047 }
3048 
3049 /**
3050  * @tc.name: GetParagraphNodes002
3051  * @tc.desc: test get paragraph nodes with multiple placeholders
3052  * @tc.type: FUNC
3053  */
3054 HWTEST_F(RichEditorTestNg, GetParagraphNodes002, TestSize.Level1)
3055 {
3056     ASSERT_NE(richEditorNode_, nullptr);
3057     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3058 
3059     // add multiple paragraphs
3060     AddImageSpan(); // length 1
3061     AddImageSpan(); // length 1
3062     AddImageSpan(); // length 1
3063 
3064     EXPECT_EQ(richEditorNode_->children_.size(), 3);
3065 
3066     auto nodes = richEditorPattern->GetParagraphNodes(1, 2);
3067     EXPECT_TRUE(nodes.empty());
3068 
3069     AddSpan(INIT_VALUE_2);
3070 
3071     // selecting only placeholder, should return span in the same paragraph
3072     nodes = richEditorPattern->GetParagraphNodes(1, 2);
3073     EXPECT_EQ(nodes.size(), 1);
3074 
3075     nodes = richEditorPattern->GetParagraphNodes(4, 6);
3076     EXPECT_EQ(nodes.size(), 1);
3077 }
3078 
3079 /**
3080  * @tc.name: GetParagraphNodes003
3081  * @tc.desc: test get paragraph nodes
3082  * @tc.type: FUNC
3083  */
3084 HWTEST_F(RichEditorTestNg, GetParagraphNodes003, TestSize.Level1)
3085 {
3086     ASSERT_NE(richEditorNode_, nullptr);
3087     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3088 
3089     AddSpan("0123");
3090     AddImageSpan();
3091     AddSpan("45789\n");
3092     AddSpan("aaaaaaaaaa");
3093 
3094     EXPECT_EQ(richEditorNode_->children_.size(), 4);
3095 
3096     auto nodes = richEditorPattern->GetParagraphNodes(50, 52);
3097     EXPECT_EQ(nodes.size(), 0);
3098 
3099     nodes = richEditorPattern->GetParagraphNodes(1, 2);
3100     EXPECT_EQ(nodes.size(), 2);
3101 }
3102 
3103 /**
3104  * @tc.name: GetParagraphLength001
3105  * @tc.desc: test get paragraph length
3106  * @tc.type: FUNC
3107  */
3108 HWTEST_F(RichEditorTestNg, GetParagraphLength001, TestSize.Level1)
3109 {
3110     ASSERT_NE(richEditorNode_, nullptr);
3111     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3112 
3113     // Add multiple paragraphs
3114     auto host = richEditorPattern->GetHost();
3115     AddImageSpan(); // length 1
3116     auto length = richEditorPattern->GetParagraphLength(host->GetChildren());
3117     EXPECT_EQ(length, 1);
3118     AddImageSpan();
3119     AddImageSpan();
3120     length = richEditorPattern->GetParagraphLength(host->GetChildren());
3121     EXPECT_EQ(length, 3);
3122     AddSpan(INIT_VALUE_1 + "\n"); // length 7
3123     length = richEditorPattern->GetParagraphLength(host->GetChildren());
3124     EXPECT_EQ(length, 10);
3125     AddImageSpan();
3126     length = richEditorPattern->GetParagraphLength(host->GetChildren());
3127     EXPECT_EQ(length, 11);
3128 }
3129 
3130 /**
3131  * @tc.name: GetCaretRect001
3132  * @tc.desc: test get caret rect
3133  * @tc.type: FUNC
3134  */
3135 HWTEST_F(RichEditorTestNg, GetCaretRect001, TestSize.Level1)
3136 {
3137     ASSERT_NE(richEditorNode_, nullptr);
3138     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3139 
3140     auto overlayMod = richEditorNode_->GetOverlayNode();
3141     auto richEditorOverlay = AceType::DynamicCast<RichEditorOverlayModifier>(richEditorPattern->overlayMod_);
3142     richEditorOverlay->SetCaretOffsetAndHeight(OffsetF(80.0f, 100.0f), 60.0f);
3143     auto caretRect = richEditorPattern->GetCaretRect();
3144 
3145     EXPECT_EQ(richEditorOverlay->GetCaretOffset(), OffsetF(80.0f, 100.0f));
3146     EXPECT_EQ(richEditorOverlay->GetCaretHeight(), 60.0f);
3147     EXPECT_EQ(caretRect.GetOffset(), richEditorOverlay->GetCaretOffset());
3148     EXPECT_EQ(caretRect.Height(), richEditorOverlay->GetCaretHeight());
3149 }
3150 
3151 /**
3152  * @tc.name: GetCaretRect002
3153  * @tc.desc: test get caret rect
3154  * @tc.type: FUNC
3155  */
3156 HWTEST_F(RichEditorTestNg, GetCaretRect002, TestSize.Level1)
3157 {
3158     ASSERT_NE(richEditorNode_, nullptr);
3159     auto manager = AceType::MakeRefPtr<TextFieldManagerNG>();
3160     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3161 
3162     auto overlayMod = richEditorNode_->GetOverlayNode();
3163     auto richEditorOverlay = AceType::DynamicCast<RichEditorOverlayModifier>(richEditorPattern->overlayMod_);
3164     richEditorOverlay->SetCaretOffsetAndHeight(OffsetF(80.0f, 100.0f), 60.0f);
3165     auto caretRect = richEditorPattern->GetCaretRect();
3166 
3167     manager->SetClickPosition({ caretRect.GetOffset().GetX(), caretRect.GetOffset().GetY() });
3168     manager->SetHeight(caretRect.Height());
3169     manager->ScrollTextFieldToSafeArea();
3170     EXPECT_EQ(GreatNotEqual(manager->GetClickPosition().GetX(), 0.0f), true);
3171     EXPECT_EQ(GreatNotEqual(manager->GetClickPosition().GetY(), 0.0f), true);
3172 
3173     EXPECT_EQ(GreatNotEqual(manager->GetHeight(), 0.0f), true);
3174     EXPECT_EQ(LessNotEqual(manager->GetHeight(), 800.0f), true);
3175 }
3176 
3177 /**
3178  * @tc.name: OnScrollCallback
3179  * @tc.desc: Verify that the OnScrollCallback interface calls normally and exits without exception.
3180  * @tc.type: FUNC
3181  */
3182 HWTEST_F(RichEditorTestNg, OnScrollCallback, TestSize.Level1)
3183 {
3184     ASSERT_NE(richEditorNode_, nullptr);
3185     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3186 
3187     int32_t SCROLL_FROM_START = 10;
3188     EXPECT_TRUE(richEditorPattern->OnScrollCallback(0, SCROLL_FROM_START));
3189 
3190     int32_t SCROLL_FROM_UPDATE = 1;
3191     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3192     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3193     EXPECT_FALSE(richEditorPattern->OnScrollCallback(10, SCROLL_FROM_UPDATE)) << "Reach Top Boundary";
3194 
3195     richEditorPattern->richTextRect_ = RectF(0, -40, 100, 140);
3196     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3197     EXPECT_FALSE(richEditorPattern->OnScrollCallback(-10, SCROLL_FROM_UPDATE)) << "Reach Bottom Boundary";
3198 
3199     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3200     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3201     EXPECT_TRUE(richEditorPattern->OnScrollCallback(-10, SCROLL_FROM_UPDATE)) << "Scroll Up 10";
3202     EXPECT_EQ(richEditorPattern->scrollOffset_, -10);
3203     EXPECT_EQ(richEditorPattern->richTextRect_.GetY(), -10);
3204 
3205     EXPECT_TRUE(richEditorPattern->OnScrollCallback(-50, SCROLL_FROM_UPDATE)) << "Scroll Up 50";
3206     EXPECT_EQ(richEditorPattern->scrollOffset_, -40);
3207     EXPECT_EQ(richEditorPattern->richTextRect_.GetY(), -40);
3208 
3209     EXPECT_TRUE(richEditorPattern->OnScrollCallback(10, SCROLL_FROM_UPDATE)) << "Scroll Down 10";
3210     EXPECT_EQ(richEditorPattern->scrollOffset_, -30);
3211     EXPECT_EQ(richEditorPattern->richTextRect_.GetY(), -30);
3212 
3213     EXPECT_TRUE(richEditorPattern->OnScrollCallback(50, SCROLL_FROM_UPDATE)) << "Scroll Down 50";
3214     EXPECT_EQ(richEditorPattern->scrollOffset_, 0);
3215     EXPECT_EQ(richEditorPattern->richTextRect_.GetY(), 0);
3216 }
3217 
3218 /**
3219  * @tc.name: MoveHandle
3220  * @tc.desc: test whether the handle is moved when scrolling.
3221  * @tc.type: FUNC
3222  */
3223 HWTEST_F(RichEditorTestNg, MoveHandle, TestSize.Level1)
3224 {
3225     ASSERT_NE(richEditorNode_, nullptr);
3226     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3227     ASSERT_NE(richEditorPattern, nullptr);
3228 
3229     richEditorPattern->textResponseType_ = TextResponseType::LONG_PRESS;
3230     richEditorPattern->selectOverlay_->ProcessOverlay({.animation = true});
3231 
3232     richEditorPattern->textSelector_.selectionBaseOffset = OffsetF(20, 20);
3233     richEditorPattern->textSelector_.firstHandle = RectF(20, 20, 20, 20);
3234     richEditorPattern->textSelector_.selectionDestinationOffset = OffsetF(60, 40);
3235     richEditorPattern->textSelector_.secondHandle = RectF(60, 40, 20, 20);
3236     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3237     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3238 
3239     richEditorPattern->OnScrollCallback(-10, SCROLL_FROM_UPDATE);
3240     EXPECT_EQ(richEditorPattern->textSelector_.selectionBaseOffset.GetY(), 10);
3241     EXPECT_EQ(richEditorPattern->textSelector_.firstHandle.GetY(), 10);
3242     EXPECT_EQ(richEditorPattern->textSelector_.selectionDestinationOffset.GetY(), 30);
3243     EXPECT_EQ(richEditorPattern->textSelector_.secondHandle.GetY(), 30);
3244 
3245     richEditorPattern->OnScrollCallback(5, SCROLL_FROM_UPDATE);
3246     EXPECT_EQ(richEditorPattern->textSelector_.selectionBaseOffset.GetY(), 15);
3247     EXPECT_EQ(richEditorPattern->textSelector_.firstHandle.GetY(), 15);
3248     EXPECT_EQ(richEditorPattern->textSelector_.selectionDestinationOffset.GetY(), 35);
3249     EXPECT_EQ(richEditorPattern->textSelector_.secondHandle.GetY(), 35);
3250 }
3251 
3252 /**
3253  * @tc.name: AutoScrollByEdgeDetection001
3254  * @tc.desc: Verify that the OnScrollCallback interface calls normally and exits without exception.
3255  * @tc.type: FUNC
3256  */
3257 HWTEST_F(RichEditorTestNg, AutoScrollByEdgeDetection001, TestSize.Level1)
3258 {
3259     ASSERT_NE(richEditorNode_, nullptr);
3260     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3261     ASSERT_NE(richEditorPattern, nullptr);
3262     auto pipeline = PipelineContext::GetCurrentContext();
3263     pipeline->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
3264     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3265     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3266 
3267     AutoScrollParam param = { .autoScrollEvent = AutoScrollEvent::HANDLE };
3268     Dimension AUTO_SCROLL_EDGE_DISTANCE = 15.0_vp;
3269     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3270     auto edgeDistance = AUTO_SCROLL_EDGE_DISTANCE.ConvertToPx();
3271 
3272     param.handleRect = RectF(50, richEditorPattern->contentRect_.GetY() + edgeDistance + 1, 20, 20);
3273     richEditorPattern->AutoScrollByEdgeDetection(
3274         param, param.handleRect.GetOffset(), EdgeDetectionStrategy::OUT_BOUNDARY);
3275     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "handle move up but not reach top edge";
3276     richEditorPattern->StopAutoScroll();
3277 
3278     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3279     param.handleRect = RectF(50, richEditorPattern->contentRect_.GetY() + edgeDistance - 1, 20, 20);
3280     richEditorPattern->AutoScrollByEdgeDetection(
3281         param, param.handleRect.GetOffset(), EdgeDetectionStrategy::OUT_BOUNDARY);
3282     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "handle reach top edge";
3283     richEditorPattern->StopAutoScroll();
3284 
3285     auto handleHeight = 20;
3286     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3287     param.handleRect =
3288         RectF(50, richEditorPattern->contentRect_.Bottom() - edgeDistance - 1 - handleHeight, 20, handleHeight);
3289     richEditorPattern->AutoScrollByEdgeDetection(
3290         param, param.handleRect.GetOffset(), EdgeDetectionStrategy::OUT_BOUNDARY);
3291     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "handle move down but not reach bottom edge";
3292     richEditorPattern->StopAutoScroll();
3293 
3294     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3295     param.handleRect =
3296         RectF(50, richEditorPattern->contentRect_.Bottom() - edgeDistance - handleHeight + 1, 20, handleHeight);
3297     richEditorPattern->AutoScrollByEdgeDetection(
3298         param, param.handleRect.GetOffset(), EdgeDetectionStrategy::OUT_BOUNDARY);
3299     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "handle reach bottom edge";
3300     richEditorPattern->StopAutoScroll();
3301 
3302     pipeline->taskExecutor_.Reset();
3303 }
3304 
3305 /**
3306  * @tc.name: AutoScrollByEdgeDetection002
3307  * @tc.desc: Verify that the OnScrollCallback interface calls normally and exits without exception.
3308  * @tc.type: FUNC
3309  */
3310 HWTEST_F(RichEditorTestNg, AutoScrollByEdgeDetection002, TestSize.Level1)
3311 {
3312     ASSERT_NE(richEditorNode_, nullptr);
3313     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3314     ASSERT_NE(richEditorPattern, nullptr);
3315     auto pipeline = PipelineContext::GetCurrentContext();
3316     pipeline->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
3317     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3318     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3319 
3320     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3321     AutoScrollParam param = { .autoScrollEvent = AutoScrollEvent::MOUSE };
3322     Dimension AUTO_SCROLL_EDGE_DISTANCE = 15.0_vp;
3323     auto edgeDistance = AUTO_SCROLL_EDGE_DISTANCE.ConvertToPx();
3324 
3325     richEditorPattern->AutoScrollByEdgeDetection(param,
3326         OffsetF(50, richEditorPattern->contentRect_.GetY() + edgeDistance + 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3327     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "mouse move up but not reach top edge";
3328     richEditorPattern->StopAutoScroll();
3329 
3330     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3331     richEditorPattern->AutoScrollByEdgeDetection(param,
3332         OffsetF(50, richEditorPattern->contentRect_.GetY() + edgeDistance - 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3333     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "mouse reach top edge";
3334     richEditorPattern->StopAutoScroll();
3335 
3336     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3337     richEditorPattern->AutoScrollByEdgeDetection(param,
3338         OffsetF(50, richEditorPattern->contentRect_.Bottom() - edgeDistance - 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3339     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "mouse move down but not reach bottom edge";
3340     richEditorPattern->StopAutoScroll();
3341 
3342     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3343     richEditorPattern->AutoScrollByEdgeDetection(param,
3344         OffsetF(50, richEditorPattern->contentRect_.Bottom() - edgeDistance + 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3345     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "mouse reach bottom edge";
3346     richEditorPattern->StopAutoScroll();
3347 
3348     pipeline->taskExecutor_.Reset();
3349 }
3350 
3351 /**
3352  * @tc.name: AutoScrollByEdgeDetection003
3353  * @tc.desc: Verify that the OnScrollCallback interface calls normally and exits without exception.
3354  * @tc.type: FUNC
3355  */
3356 HWTEST_F(RichEditorTestNg, AutoScrollByEdgeDetection003, TestSize.Level1)
3357 {
3358     ASSERT_NE(richEditorNode_, nullptr);
3359     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3360     ASSERT_NE(richEditorPattern, nullptr);
3361     auto pipeline = PipelineContext::GetCurrentContext();
3362     pipeline->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
3363     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3364     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3365 
3366     AutoScrollParam param = { .autoScrollEvent = AutoScrollEvent::DRAG };
3367     Dimension AUTO_SCROLL_DRAG_EDGE_DISTANCE = 25.0_vp;
3368     auto dragDistance = AUTO_SCROLL_DRAG_EDGE_DISTANCE.ConvertToPx();
3369 
3370     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3371     richEditorPattern->AutoScrollByEdgeDetection(
3372         param, OffsetF(50, dragDistance + 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3373     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "drag move up but not reach top edge";
3374     richEditorPattern->StopAutoScroll();
3375 
3376     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3377     richEditorPattern->AutoScrollByEdgeDetection(
3378         param, OffsetF(50, dragDistance - 10), EdgeDetectionStrategy::OUT_BOUNDARY);
3379     EXPECT_TRUE(richEditorPattern->IsReachTop()) << "drag reach top edge";
3380     EXPECT_EQ(richEditorPattern->currentScrollParam_.offset, 0) << "darg speed move up";
3381     richEditorPattern->StopAutoScroll();
3382 
3383     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3384     richEditorPattern->AutoScrollByEdgeDetection(param,
3385         OffsetF(50, richEditorPattern->contentRect_.Bottom() - dragDistance - 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3386     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "drag move down but not reach bottom edge";
3387     richEditorPattern->StopAutoScroll();
3388 
3389     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3390     richEditorPattern->AutoScrollByEdgeDetection(param,
3391         OffsetF(50, richEditorPattern->contentRect_.Bottom() - dragDistance + 1), EdgeDetectionStrategy::OUT_BOUNDARY);
3392     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "drag reach bottom edge";
3393     richEditorPattern->StopAutoScroll();
3394 
3395     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3396     richEditorPattern->contentRect_ = RectF(0, 0, 100, dragDistance - 1);
3397     richEditorPattern->AutoScrollByEdgeDetection(param, OffsetF(50, 50), EdgeDetectionStrategy::OUT_BOUNDARY);
3398     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "content height is too small.";
3399     richEditorPattern->StopAutoScroll();
3400 
3401     pipeline->taskExecutor_.Reset();
3402 }
3403 
3404 /*
3405  * @tc.name: DoubleHandleClickEvent002
3406  * @tc.desc: test Mouse Double Click
3407  * @tc.type: FUNC
3408  */
3409 HWTEST_F(RichEditorTestNg, DoubleHandleClickEvent002, TestSize.Level1)
3410 {
3411     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3412     AddSpan(TEST_INSERT_VALUE);
3413 
3414     TestParagraphRect paragraphRect = { .start = 0, .end = 1, .rects = { { -400.0, -400.0, 200.0, 200.0 } } };
3415     TestParagraphItem paragraphItem = { .start = 0, .end = 1,
3416         .indexOffsetMap = { { 0, Offset(0, 0) }, { 6, Offset(50, 0) } },
3417         .testParagraphRects = { paragraphRect } };
3418     AddParagraph(paragraphItem);
3419 
3420     GestureEvent info;
3421     richEditorPattern->isMousePressed_ = true;
3422     info.SetSourceDevice(SourceType::MOUSE);
3423     richEditorPattern->textSelector_.baseOffset = -1;
3424     richEditorPattern->textSelector_.destinationOffset = -1;
3425     richEditorPattern->caretUpdateType_ = CaretUpdateType::DOUBLE_CLICK;
3426     richEditorPattern->caretPosition_ = 0;
3427     info.localLocation_ = Offset(0, 0);
3428     richEditorPattern->isMouseSelect_ = false;
3429     richEditorPattern->caretVisible_ = true;
3430     richEditorPattern->contentRect_ = { -500.0, -500.0, 500.0, 500.0 };
3431     richEditorPattern->HandleDoubleClickOrLongPress(info);
3432     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
3433     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 1);
3434 
3435     richEditorPattern->textSelector_.baseOffset = -1;
3436     richEditorPattern->textSelector_.destinationOffset = -1;
3437     richEditorPattern->caretUpdateType_ = CaretUpdateType::LONG_PRESSED;
3438     richEditorPattern->HandleDoubleClickOrLongPress(info);
3439     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, -1);
3440     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, -1);
3441 }
3442 
3443 /**
3444  * @tc.name: AutoScrollByEdgeDetection004
3445  * @tc.desc: Verify that the OnScrollCallback interface calls normally and exits without exception.
3446  * @tc.type: FUNC
3447  */
3448 HWTEST_F(RichEditorTestNg, AutoScrollByEdgeDetection004, TestSize.Level1)
3449 {
3450     ASSERT_NE(richEditorNode_, nullptr);
3451     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3452     ASSERT_NE(richEditorPattern, nullptr);
3453     auto pipeline = PipelineContext::GetCurrentContext();
3454     pipeline->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
3455     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3456     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3457 
3458     Dimension AUTO_SCROLL_EDGE_DISTANCE = 15.0_vp;
3459     auto edgeDistance = AUTO_SCROLL_EDGE_DISTANCE.ConvertToPx();
3460 
3461     richEditorPattern->prevAutoScrollOffset_ = OffsetF(50, 50);
3462     AutoScrollParam param = { .autoScrollEvent = AutoScrollEvent::HANDLE, .handleRect = RectF(50, 50, 20, 20) };
3463     richEditorPattern->AutoScrollByEdgeDetection(param, OffsetF(50, 50), EdgeDetectionStrategy::OUT_BOUNDARY);
3464     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "the touch point is the same as the last time";
3465     richEditorPattern->StopAutoScroll();
3466 
3467     richEditorPattern->prevAutoScrollOffset_ = OffsetF(0, 0);
3468     richEditorPattern->contentRect_ = RectF(0, 0, 100, edgeDistance - 1);
3469     richEditorPattern->AutoScrollByEdgeDetection(
3470         param, param.handleRect.GetOffset(), EdgeDetectionStrategy::OUT_BOUNDARY);
3471     EXPECT_FALSE(richEditorPattern->autoScrollTask_) << "content height is too small.";
3472     richEditorPattern->StopAutoScroll();
3473 
3474     pipeline->taskExecutor_.Reset();
3475 }
3476 
3477 /**
3478  * @tc.name: CheckScrollable
3479  * @tc.desc: test CheckScrollable.
3480  * @tc.type: FUNC
3481  */
3482 HWTEST_F(RichEditorTestNg, CheckScrollable, TestSize.Level1)
3483 {
3484     ASSERT_NE(richEditorNode_, nullptr);
3485     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3486     ASSERT_NE(richEditorPattern, nullptr);
3487     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 140);
3488     richEditorPattern->contentRect_ = RectF(0, 0, 100, 100);
3489 
3490     richEditorPattern->CheckScrollable();
3491     EXPECT_FALSE(richEditorPattern->scrollable_);
3492 
3493     AddSpan(TEST_INSERT_VALUE);
3494     richEditorPattern->CheckScrollable();
3495     EXPECT_TRUE(richEditorPattern->scrollable_);
3496 
3497     richEditorPattern->richTextRect_ = RectF(0, 0, 100, 80);
3498     richEditorPattern->CheckScrollable();
3499     EXPECT_FALSE(richEditorPattern->scrollable_);
3500 
3501     ClearSpan();
3502 }
3503 
3504 /**
3505  * @tc.name: NeedSoftKeyboard001
3506  * @tc.desc: test NeedSoftKeyboard
3507  * @tc.type: FUNC
3508  */
3509 HWTEST_F(RichEditorTestNg, NeedSoftKeyboard001, TestSize.Level1)
3510 {
3511         /**
3512          * @tc.step: step1. Get frameNode and pattern.
3513          */
3514         ASSERT_NE(richEditorNode_, nullptr);
3515         auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3516         ASSERT_NE(richEditorPattern, nullptr);
3517 
3518         /**
3519          * @tc.steps: step2. Test whether rich editor need soft keyboard.
3520          */
3521         EXPECT_TRUE(richEditorPattern->NeedSoftKeyboard());
3522 }
3523 /*
3524  * @tc.name: DoubleHandleClickEvent001
3525  * @tc.desc: test double click
3526  * @tc.type: FUNC
3527  */
3528 HWTEST_F(RichEditorTestNg, DoubleHandleClickEvent001, TestSize.Level1)
3529 {
3530     ASSERT_NE(richEditorNode_, nullptr);
3531     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3532     ASSERT_NE(richEditorPattern, nullptr);
3533     AddSpan(INIT_VALUE_1);
3534     GestureEvent info;
3535     info.localLocation_ = Offset(0, 0);
3536     richEditorPattern->isMouseSelect_ = false;
3537     richEditorPattern->caretVisible_ = true;
3538     richEditorPattern->HandleDoubleClickEvent(info);
3539     EXPECT_TRUE(richEditorPattern->caretVisible_);
3540 
3541     AddSpan(INIT_VALUE_3);
3542     info.localLocation_ = Offset(50, 50);
3543     richEditorPattern->textSelector_.baseOffset = -1;
3544     richEditorPattern->textSelector_.destinationOffset = -1;
3545     richEditorPattern->HandleDoubleClickEvent(info);
3546     EXPECT_NE(richEditorPattern->textSelector_.baseOffset, -1);
3547     EXPECT_NE(richEditorPattern->textSelector_.destinationOffset, -1);
3548     EXPECT_NE(richEditorPattern->caretPosition_, -1);
3549 
3550     info.localLocation_ = Offset(0, 0);
3551     richEditorPattern->isMouseSelect_ = true;
3552     richEditorPattern->textSelector_.baseOffset = -1;
3553     richEditorPattern->textSelector_.destinationOffset = -1;
3554     richEditorPattern->HandleDoubleClickEvent(info);
3555     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
3556     EXPECT_EQ(richEditorPattern->textSelector_.destinationOffset, 0);
3557 }
3558 
3559 /*
3560  * @tc.name: DoubleHandleClickEvent001
3561  * @tc.desc: test double click
3562  * @tc.type: FUNC
3563  */
3564 HWTEST_F(RichEditorTestNg, AdjustWordCursorAndSelect01, TestSize.Level1)
3565 {
3566     using namespace std::chrono;
3567     ASSERT_NE(richEditorNode_, nullptr);
3568     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3569     ASSERT_NE(richEditorPattern, nullptr);
3570 
3571     AddSpan(INIT_VALUE_1);
3572     int32_t pos = 3;
3573 
3574     MockDataDetectorMgr mockDataDetectorMgr;
3575     InitAdjustObject(mockDataDetectorMgr);
3576 
3577     richEditorPattern->lastAiPosTimeStamp_ = high_resolution_clock::now();
3578     richEditorPattern->lastClickTimeStamp_ = richEditorPattern->lastAiPosTimeStamp_ + seconds(2);
3579     int32_t spanStart = -1;
3580     std::string content = richEditorPattern->GetPositionSpansText(pos, spanStart);
3581     mockDataDetectorMgr.AdjustCursorPosition(pos, content, richEditorPattern->lastAiPosTimeStamp_,
3582                                              richEditorPattern->lastClickTimeStamp_);
3583     EXPECT_EQ(pos, 2);
3584 
3585     int32_t start = 1;
3586     int32_t end = 3;
3587     mockDataDetectorMgr.AdjustWordSelection(pos, content, start, end);
3588     EXPECT_EQ(start, 2);
3589     EXPECT_EQ(end, 3);
3590 
3591     AddSpan(INIT_VALUE_2);
3592     pos = 1;
3593     content = richEditorPattern->GetPositionSpansText(pos, spanStart);
3594     mockDataDetectorMgr.AdjustCursorPosition(pos, content, richEditorPattern->lastAiPosTimeStamp_,
3595                                              richEditorPattern->lastClickTimeStamp_);
3596     EXPECT_EQ(pos, 4);
3597 
3598     start = 1;
3599     end = 3;
3600     mockDataDetectorMgr.AdjustWordSelection(pos, content, start, end);
3601     EXPECT_EQ(start, 0);
3602     EXPECT_EQ(end, 2);
3603 
3604     ClearSpan();
3605     pos = 2;
3606     content = richEditorPattern->GetPositionSpansText(pos, spanStart);
3607     mockDataDetectorMgr.AdjustCursorPosition(pos, content, richEditorPattern->lastAiPosTimeStamp_,
3608                                              richEditorPattern->lastClickTimeStamp_);
3609     EXPECT_EQ(pos, -1);
3610 
3611     start = 1;
3612     end = 3;
3613     mockDataDetectorMgr.AdjustWordSelection(pos, content, start, end);
3614     EXPECT_EQ(start, -1);
3615     EXPECT_EQ(end, -1);
3616 }
3617 
3618 /**
3619  * @tc.name: RichEditorController011
3620  * @tc.desc: test add symbol span
3621  * @tc.type: FUNC
3622  */
3623 HWTEST_F(RichEditorTestNg, RichEditorController011, TestSize.Level1)
3624 {
3625     /**
3626      * @tc.steps: step1. get richEditor controller
3627      */
3628     ASSERT_NE(richEditorNode_, nullptr);
3629     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3630     ASSERT_NE(richEditorPattern, nullptr);
3631     auto richEditorController = richEditorPattern->GetRichEditorController();
3632     ASSERT_NE(richEditorController, nullptr);
3633 
3634     /**
3635      * @tc.steps: step2. initalize symbol span properties
3636      */
3637     TextStyle style;
3638     style.SetFontSize(FONT_SIZE_VALUE);
3639     style.SetFontWeight(FONT_WEIGHT_VALUE);
3640     style.SetSymbolColorList(SYMBOL_COLOR_LIST_1);
3641     style.SetRenderStrategy(RENDER_STRATEGY_SINGLE);
3642     style.SetEffectStrategy(EFFECT_STRATEGY_NONE);
3643     SymbolSpanOptions options;
3644     options.symbolId = SYMBOL_ID;
3645     options.style = style;
3646 
3647     /**
3648      * @tc.steps: step3. test add symbol span
3649      */
3650     auto index1 = richEditorController->AddSymbolSpan(options);
3651     EXPECT_EQ(index1, 0);
3652     auto index2 = richEditorController->AddSymbolSpan(options);
3653     EXPECT_EQ(index2, 1);
3654     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 2);
3655     ClearSpan();
3656 }
3657 
3658 /**
3659  * @tc.name: RichEditorController012
3660  * @tc.desc: test update symbol span
3661  * @tc.type: FUNC
3662  */
3663 HWTEST_F(RichEditorTestNg, RichEditorController012, TestSize.Level1)
3664 {
3665     /**
3666      * @tc.steps: step1. get richEditor controller
3667      */
3668     ASSERT_NE(richEditorNode_, nullptr);
3669     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3670     ASSERT_NE(richEditorPattern, nullptr);
3671     auto richEditorController = richEditorPattern->GetRichEditorController();
3672     ASSERT_NE(richEditorController, nullptr);
3673 
3674     /**
3675      * @tc.steps: step2. initalize symbol span properties
3676      */
3677     TextStyle style;
3678     style.SetFontSize(FONT_SIZE_VALUE);
3679     style.SetFontWeight(FONT_WEIGHT_VALUE);
3680     style.SetSymbolColorList(SYMBOL_COLOR_LIST_1);
3681     style.SetRenderStrategy(RENDER_STRATEGY_SINGLE);
3682     style.SetEffectStrategy(EFFECT_STRATEGY_NONE);
3683     SymbolSpanOptions options;
3684     options.symbolId = SYMBOL_ID;
3685     options.style = style;
3686 
3687     /**
3688      * @tc.steps: step3. add symbol span
3689      */
3690     auto index1 = richEditorController->AddSymbolSpan(options);
3691     EXPECT_EQ(index1, 0);
3692     auto index2 = richEditorController->AddSymbolSpan(options);
3693     EXPECT_EQ(index2, 1);
3694 
3695     /**
3696      * @tc.steps: step4. update symbol span style
3697      */
3698     struct UpdateSpanStyle updateSpanStyle;
3699     updateSpanStyle.updateFontSize = FONT_SIZE_VALUE_2;
3700     updateSpanStyle.updateFontWeight = FONT_WEIGHT_BOLD;
3701     updateSpanStyle.updateSymbolColor = SYMBOL_COLOR_LIST_2;
3702     updateSpanStyle.updateSymbolRenderingStrategy = RENDER_STRATEGY_MULTI_COLOR;
3703     updateSpanStyle.updateSymbolEffectStrategy = EFFECT_STRATEGY_SCALE;
3704     richEditorController->SetUpdateSpanStyle(updateSpanStyle);
3705 
3706     ImageSpanAttribute imageStyle;
3707     style.SetFontSize(FONT_SIZE_VALUE_2);
3708     style.SetFontWeight(FONT_WEIGHT_BOLD);
3709     style.SetSymbolColorList(SYMBOL_COLOR_LIST_2);
3710     style.SetRenderStrategy(RENDER_STRATEGY_MULTI_COLOR);
3711     style.SetEffectStrategy(EFFECT_STRATEGY_SCALE);
3712 
3713     // update the first symbol span
3714     richEditorController->UpdateSpanStyle(0, 2, style, imageStyle);
3715 
3716     /**
3717      * @tc.steps: step5. test symbol span style
3718      */
3719     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
3720     ASSERT_NE(newSpan1, nullptr);
3721     EXPECT_EQ(newSpan1->GetFontSize(), FONT_SIZE_VALUE_2);
3722     EXPECT_EQ(newSpan1->GetFontWeight(), FONT_WEIGHT_BOLD);
3723     EXPECT_EQ(newSpan1->GetSymbolColorList(), SYMBOL_COLOR_LIST_2);
3724     EXPECT_EQ(newSpan1->GetSymbolRenderingStrategy(), RENDER_STRATEGY_MULTI_COLOR);
3725     EXPECT_EQ(newSpan1->GetSymbolEffectStrategy(), EFFECT_STRATEGY_SCALE);
3726 
3727     auto newSpan2 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(1));
3728     ASSERT_NE(newSpan2, nullptr);
3729     EXPECT_EQ(newSpan2->GetFontSize(), FONT_SIZE_VALUE);
3730     EXPECT_EQ(newSpan2->GetFontWeight(), FONT_WEIGHT_VALUE);
3731     EXPECT_EQ(newSpan2->GetSymbolColorList(), SYMBOL_COLOR_LIST_1);
3732     EXPECT_EQ(newSpan2->GetSymbolRenderingStrategy(), RENDER_STRATEGY_SINGLE);
3733     EXPECT_EQ(newSpan2->GetSymbolEffectStrategy(), EFFECT_STRATEGY_NONE);
3734 
3735     ClearSpan();
3736 }
3737 
3738 /**
3739  * @tc.name: RichEditorController013
3740  * @tc.desc: test get symbol span info
3741  * @tc.type: FUNC
3742  */
3743 HWTEST_F(RichEditorTestNg, RichEditorController013, TestSize.Level1)
3744 {
3745     /**
3746      * @tc.steps: step1. get richEditor controller
3747      */
3748     ASSERT_NE(richEditorNode_, nullptr);
3749     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3750     ASSERT_NE(richEditorPattern, nullptr);
3751     auto richEditorController = richEditorPattern->GetRichEditorController();
3752     ASSERT_NE(richEditorController, nullptr);
3753 
3754     /**
3755      * @tc.steps: step2. initalize symbol span properties
3756      */
3757     TextStyle style;
3758     style.SetFontSize(FONT_SIZE_VALUE);
3759     style.SetFontWeight(FONT_WEIGHT_VALUE);
3760     style.SetSymbolColorList(SYMBOL_COLOR_LIST_1);
3761     style.SetRenderStrategy(RENDER_STRATEGY_SINGLE);
3762     style.SetEffectStrategy(EFFECT_STRATEGY_NONE);
3763     SymbolSpanOptions options;
3764     options.symbolId = SYMBOL_ID;
3765     options.style = style;
3766 
3767     /**
3768      * @tc.steps: step3. add symbol span
3769      */
3770     auto index1 = richEditorController->AddSymbolSpan(options);
3771     EXPECT_EQ(index1, 0);
3772     auto index2 = richEditorController->AddSymbolSpan(options);
3773     EXPECT_EQ(index2, 1);
3774     auto index3 = richEditorController->AddSymbolSpan(options);
3775     EXPECT_EQ(index3, 2);
3776     auto index4 = richEditorController->AddSymbolSpan(options);
3777     EXPECT_EQ(index4, 3);
3778 
3779     /**
3780      * @tc.steps: step4. get symbol span info
3781      */
3782     auto info1 = richEditorController->GetSpansInfo(2, 5);
3783     EXPECT_EQ(info1.selection_.selection[0], 2);
3784     EXPECT_EQ(info1.selection_.selection[1], 5);
3785     EXPECT_EQ(info1.selection_.resultObjects.size(), 2);
3786 
3787     auto info2 = richEditorController->GetSpansInfo(5, 2);
3788     EXPECT_EQ(info2.selection_.selection[0], 2);
3789     EXPECT_EQ(info2.selection_.selection[1], 5);
3790     EXPECT_EQ(info2.selection_.resultObjects.size(), 2);
3791 
3792     auto info3 = richEditorController->GetSpansInfo(-2, 5);
3793     EXPECT_EQ(info3.selection_.selection[0], 0);
3794     EXPECT_EQ(info3.selection_.selection[1], 5);
3795     EXPECT_EQ(info3.selection_.resultObjects.size(), 3);
3796 
3797     auto info4 = richEditorController->GetSpansInfo(2, -5);
3798     EXPECT_EQ(info4.selection_.selection[0], 0);
3799     EXPECT_EQ(info4.selection_.selection[1], 2);
3800     EXPECT_EQ(info4.selection_.resultObjects.size(), 1);
3801 
3802     ClearSpan();
3803 }
3804 
3805 /**
3806  * @tc.name: RichEditorController014
3807  * @tc.desc: test delete symbol span
3808  * @tc.type: FUNC
3809  */
3810 HWTEST_F(RichEditorTestNg, RichEditorController014, TestSize.Level1)
3811 {
3812     /**
3813      * @tc.steps: step1. get richEditor controller
3814      */
3815     ASSERT_NE(richEditorNode_, nullptr);
3816     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3817     ASSERT_NE(richEditorPattern, nullptr);
3818     auto richEditorController = richEditorPattern->GetRichEditorController();
3819     ASSERT_NE(richEditorController, nullptr);
3820 
3821     /**
3822      * @tc.steps: step2. initalize symbol span properties
3823      */
3824     TextStyle style;
3825     style.SetFontSize(FONT_SIZE_VALUE);
3826     SymbolSpanOptions options;
3827     options.symbolId = SYMBOL_ID;
3828     options.style = style;
3829 
3830     /**
3831      * @tc.steps: step3. add symbol span
3832      */
3833     auto index1 = richEditorController->AddSymbolSpan(options);
3834     EXPECT_EQ(index1, 0);
3835     auto index2 = richEditorController->AddSymbolSpan(options);
3836     EXPECT_EQ(index2, 1);
3837     auto index3 = richEditorController->AddSymbolSpan(options);
3838     EXPECT_EQ(index3, 2);
3839     auto index4 = richEditorController->AddSymbolSpan(options);
3840     EXPECT_EQ(index4, 3);
3841     EXPECT_EQ(richEditorNode_->GetChildren().size(), 4);
3842 
3843     /**
3844      * @tc.steps: step4. delete single symbol span
3845      */
3846     RangeOptions option2;
3847     option2.start = 0;
3848     option2.end = 2;
3849     richEditorController->DeleteSpans(option2);
3850     EXPECT_EQ(richEditorNode_->GetChildren().size(), 3);
3851 
3852     option2.start = 2;
3853     option2.end = 0;
3854     richEditorController->DeleteSpans(option2);
3855     EXPECT_EQ(richEditorNode_->GetChildren().size(), 2);
3856 
3857     option2.start = -1;
3858     option2.end = 2;
3859     richEditorController->DeleteSpans(option2);
3860     EXPECT_EQ(richEditorNode_->GetChildren().size(), 1);
3861 
3862     option2.start = 2;
3863     option2.end = -1;
3864     richEditorController->DeleteSpans(option2);
3865     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
3866 
3867     /**
3868      * @tc.steps: step5. add symbol span
3869      */
3870     auto index5 = richEditorController->AddSymbolSpan(options);
3871     EXPECT_EQ(index5, 0);
3872 
3873     /**
3874      * @tc.steps: step6. delete symbol span
3875      * If half of a SymbolSpan is deleted, the entire SymbolSpan will be removed.
3876      */
3877     option2.start = 0;
3878     option2.end = 1;
3879     richEditorController->DeleteSpans(option2);
3880     EXPECT_EQ(richEditorNode_->GetChildren().size(), 0);
3881 
3882     ClearSpan();
3883 }
3884 
3885 /**
3886  * @tc.name: RichEditorController015
3887  * @tc.desc: test use span & imagespan & symbolspan together
3888  * @tc.type: FUNC
3889  */
3890 HWTEST_F(RichEditorTestNg, RichEditorController015, TestSize.Level1)
3891 {
3892     /**
3893      * @tc.steps: step1. get richEditor controller
3894      */
3895     ASSERT_NE(richEditorNode_, nullptr);
3896     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3897     ASSERT_NE(richEditorPattern, nullptr);
3898     auto richEditorController = richEditorPattern->GetRichEditorController();
3899     ASSERT_NE(richEditorController, nullptr);
3900 
3901     /**
3902      * @tc.steps: step2. initalize span properties
3903      */
3904     SymbolSpanOptions options1;
3905     options1.symbolId = SYMBOL_ID;
3906     TextSpanOptions options2;
3907     options2.value = INIT_VALUE_1;
3908     ImageSpanOptions options3;
3909     options3.image = IMAGE_VALUE;
3910 
3911     /**
3912      * @tc.steps: step3. test add span
3913      */
3914     richEditorController->AddSymbolSpan(options1);
3915     richEditorController->AddTextSpan(options2);
3916     richEditorController->AddImageSpan(options3);
3917     richEditorController->AddTextSpan(options2);
3918     richEditorController->AddSymbolSpan(options1);
3919     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 5);
3920 
3921     /**
3922      * @tc.steps: step4. test get span
3923      */
3924     auto info1 = richEditorController->GetSpansInfo(0, 3);
3925     EXPECT_EQ(info1.selection_.resultObjects.size(), 2);
3926     auto info2 = richEditorController->GetSpansInfo(8, 9);
3927     EXPECT_EQ(info2.selection_.resultObjects.size(), 1);
3928 
3929     /**
3930      * @tc.steps: step5. test update span
3931      */
3932     TextStyle textStyle;
3933     textStyle.SetFontSize(FONT_SIZE_VALUE_2);
3934     struct UpdateSpanStyle updateSpanStyle;
3935     updateSpanStyle.updateFontSize = FONT_SIZE_VALUE_2;
3936 
3937     richEditorController->SetUpdateSpanStyle(updateSpanStyle);
3938     ImageSpanAttribute imageStyle;
3939     richEditorController->UpdateSpanStyle(2, 8, textStyle, imageStyle);
3940 
3941     auto newSpan2 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(1));
3942     ASSERT_NE(newSpan2, nullptr);
3943     EXPECT_EQ(newSpan2->GetFontSize(), FONT_SIZE_VALUE_2);
3944 
3945     /**
3946      * @tc.steps: step6. test delete span
3947      */
3948     RangeOptions option;
3949     option.start = 8;
3950     option.end = 15;
3951     richEditorController->DeleteSpans(option);
3952     EXPECT_EQ(richEditorNode_->GetChildren().size(), 3);
3953 
3954     option.start = 0;
3955     option.end = 2;
3956     richEditorController->DeleteSpans(option);
3957     EXPECT_EQ(richEditorNode_->GetChildren().size(), 2);
3958 
3959     ClearSpan();
3960 }
3961 
3962 /**
3963  * @tc.name: RichEditorController016
3964  * @tc.desc: test add many spans
3965  * @tc.type: FUNC
3966  */
3967 HWTEST_F(RichEditorTestNg, RichEditorController016, TestSize.Level1)
3968 {
3969     /**
3970      * @tc.steps: step1. get richEditor controller
3971      */
3972     ASSERT_NE(richEditorNode_, nullptr);
3973     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
3974     ASSERT_NE(richEditorPattern, nullptr);
3975     auto richEditorController = richEditorPattern->GetRichEditorController();
3976     ASSERT_NE(richEditorController, nullptr);
3977 
3978     /**
3979      * @tc.steps: step2. initalize span properties
3980      */
3981     SymbolSpanOptions options1;
3982     options1.symbolId = SYMBOL_ID;
3983     TextSpanOptions options2;
3984     options2.value = INIT_VALUE_1;
3985     ImageSpanOptions options3;
3986     options3.image = IMAGE_VALUE;
3987 
3988     /**
3989      * @tc.steps: step3. test add span
3990      */
3991     for (int i = 0; i < 100; i++) {
3992         richEditorController->AddSymbolSpan(options1);
3993         richEditorController->AddTextSpan(options2);
3994         richEditorController->AddImageSpan(options3);
3995         richEditorController->AddTextSpan(options2);
3996         richEditorController->AddSymbolSpan(options1);
3997     }
3998     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 500);
3999 
4000     ClearSpan();
4001 }
4002 
4003 /**
4004  * @tc.name: RichEditorModel017
4005  * @tc.desc: test paragraph style linebreakstrategy attribute
4006  * @tc.type: FUNC
4007  */
4008 HWTEST_F(RichEditorTestNg, RichEditorModel017, TestSize.Level1)
4009 {
4010     ASSERT_NE(richEditorNode_, nullptr);
4011     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4012     ASSERT_NE(richEditorPattern, nullptr);
4013     auto richEditorController = richEditorPattern->GetRichEditorController();
4014     ASSERT_NE(richEditorController, nullptr);
4015     TextSpanOptions options;
4016     options.value = INIT_VALUE_1;
4017 
4018     // test paragraph  style linebreakstrategy default value
4019     richEditorController->AddTextSpan(options);
4020     auto info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
4021     EXPECT_EQ(static_cast<LineBreakStrategy>(info[0].lineBreakStrategy), LineBreakStrategy::GREEDY);
4022 
4023     // test paragraph style linebreakstrategy value of LineBreakStrategy.GREEDY
4024     struct UpdateParagraphStyle style;
4025     style.lineBreakStrategy = LineBreakStrategy::GREEDY;
4026     richEditorController->UpdateParagraphStyle(1, sizeof(INIT_VALUE_1), style);
4027     info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
4028     EXPECT_EQ(static_cast<LineBreakStrategy>(info[0].lineBreakStrategy), LineBreakStrategy::GREEDY);
4029 
4030     // test paragraph style linebreakstrategy value of LineBreakStrategy.HIGH_QUALITY
4031     style.lineBreakStrategy = LineBreakStrategy::HIGH_QUALITY;
4032     richEditorController->UpdateParagraphStyle(1, sizeof(INIT_VALUE_1), style);
4033     info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
4034     EXPECT_EQ(static_cast<LineBreakStrategy>(info[0].lineBreakStrategy), LineBreakStrategy::HIGH_QUALITY);
4035 
4036     // test paragraph style linebreakstrategy value of LineBreakStrategy.BALANCED
4037     style.lineBreakStrategy = LineBreakStrategy::BALANCED;
4038     richEditorController->UpdateParagraphStyle(1, sizeof(INIT_VALUE_1), style);
4039     info = richEditorController->GetParagraphsInfo(1, sizeof(INIT_VALUE_1));
4040     EXPECT_EQ(static_cast<LineBreakStrategy>(info[0].lineBreakStrategy), LineBreakStrategy::BALANCED);
4041 }
4042 
4043 /**
4044  * @tc.name: RichEditorDragTest003
4045  * @tc.desc: test the drag of RichEditor with developer's onDragDrop function
4046  * @tc.type: FUNC
4047  */
4048 HWTEST_F(RichEditorTestNg, RichEditorDragTest003, TestSize.Level1)
4049 {
4050     RichEditorModelNG model;
4051     model.Create();
4052     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
4053     ASSERT_NE(host, nullptr);
4054     host->draggable_ = true;
4055     auto eventHub = host->GetEventHub<EventHub>();
4056     ASSERT_NE(eventHub, nullptr);
4057     auto pattern = host->GetPattern<RichEditorPattern>();
4058     ASSERT_NE(pattern, nullptr);
4059     auto gesture = host->GetOrCreateGestureEventHub();
4060     ASSERT_NE(gesture, nullptr);
4061     EXPECT_TRUE(gesture->GetTextDraggable());
4062     gesture->SetIsTextDraggable(true);
4063     pattern->InitDragDropEvent();
4064     EXPECT_TRUE(eventHub->HasDefaultOnDragStart());
4065     EXPECT_TRUE(eventHub->HasOnDrop());
4066     auto controller = pattern->GetRichEditorController();
4067     ASSERT_NE(controller, nullptr);
4068     TextStyle style;
4069     TextSpanOptions options;
4070     options.value = INIT_VALUE_3;
4071     options.style = style;
4072     auto index = controller->AddTextSpan(options);
4073     EXPECT_EQ(index, 0);
4074     pattern->textSelector_.Update(0, 6);
4075     auto event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
4076     eventHub->FireOnDrop(event, "");
4077     EXPECT_EQ(pattern->status_, Status::NONE);
4078     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4079         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4080     }
4081 }
4082 
4083 /**
4084  * @tc.name: RichEditorDragTest004
4085  * @tc.desc: test the drag of RichEditor with developer's HandleOnDragDropTextOperation function
4086  * @tc.type: FUNC
4087  */
4088 HWTEST_F(RichEditorTestNg, RichEditorDragTest004, TestSize.Level1)
4089 {
4090     RichEditorModelNG model;
4091     model.Create();
4092     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
4093     ASSERT_NE(host, nullptr);
4094     host->draggable_ = true;
4095     auto eventHub = host->GetEventHub<EventHub>();
4096     ASSERT_NE(eventHub, nullptr);
4097     auto pattern = host->GetPattern<RichEditorPattern>();
4098     ASSERT_NE(pattern, nullptr);
4099     auto gesture = host->GetOrCreateGestureEventHub();
4100     ASSERT_NE(gesture, nullptr);
4101     EXPECT_TRUE(gesture->GetTextDraggable());
4102     gesture->SetIsTextDraggable(true);
4103     pattern->InitDragDropEvent();
4104     EXPECT_TRUE(eventHub->HasOnDrop());
4105     auto controller = pattern->GetRichEditorController();
4106     ASSERT_NE(controller, nullptr);
4107     TextStyle style;
4108     TextSpanOptions options;
4109     options.value = INIT_VALUE_1 + INIT_VALUE_1;
4110     options.style = style;
4111     auto index = controller->AddTextSpan(options);
4112     EXPECT_EQ(index, 0);
4113     pattern->dragRange_.first = 0;
4114     pattern->caretPosition_ = options.value.length();
4115     pattern->HandleOnDragDropTextOperation(INIT_VALUE_1, true);
4116     pattern->dragRange_.first = options.value.length();
4117     pattern->caretPosition_ = 0;
4118     pattern->HandleOnDragDropTextOperation(INIT_VALUE_1, true);
4119     EXPECT_EQ(pattern->status_, Status::NONE);
4120     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4121         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4122     }
4123 }
4124 
4125 /**
4126  * @tc.name: RichEditorDragTest001
4127  * @tc.desc: test the drag of RichEditor without developer's onDragStart function
4128  * @tc.type: FUNC
4129  */
4130 HWTEST_F(RichEditorTestNg, RichEditorDragTest001, TestSize.Level1)
4131 {
4132     RichEditorModelNG model;
4133     model.Create();
4134     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
4135     ASSERT_NE(host, nullptr);
4136     host->draggable_ = true;
4137     auto eventHub = host->GetEventHub<EventHub>();
4138     ASSERT_NE(eventHub, nullptr);
4139     auto pattern = host->GetPattern<RichEditorPattern>();
4140     ASSERT_NE(pattern, nullptr);
4141     auto gesture = host->GetOrCreateGestureEventHub();
4142     ASSERT_NE(gesture, nullptr);
4143     EXPECT_TRUE(gesture->GetTextDraggable());
4144     gesture->SetIsTextDraggable(true);
4145     pattern->InitDragDropEvent();
4146     EXPECT_TRUE(eventHub->HasDefaultOnDragStart());
4147     auto controller = pattern->GetRichEditorController();
4148     ASSERT_NE(controller, nullptr);
4149     TextStyle style;
4150     TextSpanOptions options;
4151     options.value = INIT_VALUE_1;
4152     options.style = style;
4153     auto index = controller->AddTextSpan(options);
4154     EXPECT_EQ(index, 0);
4155     ImageSpanOptions imageOptions;
4156     imageOptions.image = IMAGE_VALUE;
4157     controller->AddImageSpan(imageOptions);
4158     pattern->textSelector_.Update(0, 6);
4159     auto onDragStart = eventHub->GetDefaultOnDragStart();
4160     auto event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
4161     auto dragDropInfo = onDragStart(event, "");
4162     EXPECT_EQ(dragDropInfo.extraInfo, "");
4163     EXPECT_EQ(pattern->textSelector_.GetTextStart(), -1);
4164     EXPECT_EQ(pattern->textSelector_.GetTextEnd(), -1);
4165     EXPECT_EQ(pattern->status_, Status::DRAGGING);
4166     eventHub->FireOnDragMove(event, "");
4167     auto onDragEnd = eventHub->GetOnDragEnd();
4168     onDragEnd(event);
4169     EXPECT_EQ(pattern->status_, Status::NONE);
4170     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4171         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4172     }
4173 }
4174 
4175 /**
4176  * @tc.name: RichEditorDragTest002
4177  * @tc.desc: test the drag of RichEditor with developer's onDragStart function
4178  * @tc.type: FUNC
4179  */
4180 HWTEST_F(RichEditorTestNg, RichEditorDragTest002, TestSize.Level1)
4181 {
4182     RichEditorModelNG model;
4183     model.Create();
4184     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
4185     ASSERT_NE(host, nullptr);
4186     host->draggable_ = true;
4187     auto eventHub = host->GetEventHub<EventHub>();
4188     ASSERT_NE(eventHub, nullptr);
4189     auto pattern = host->GetPattern<RichEditorPattern>();
4190     ASSERT_NE(pattern, nullptr);
4191     auto gesture = host->GetOrCreateGestureEventHub();
4192     ASSERT_NE(gesture, nullptr);
4193     EXPECT_TRUE(gesture->GetTextDraggable());
4194     gesture->SetIsTextDraggable(true);
__anon814dfc0d1b02(const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams) 4195     auto dragStart = [](const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams) -> NG::DragDropInfo {
4196         NG::DragDropInfo info;
4197         info.extraInfo = INIT_VALUE_1;
4198         return info;
4199     };
4200     eventHub->SetOnDragStart(std::move(dragStart));
4201     EXPECT_TRUE(eventHub->HasOnDragStart());
4202     pattern->InitDragDropEvent();
4203     EXPECT_TRUE(eventHub->HasDefaultOnDragStart());
4204     auto controller = pattern->GetRichEditorController();
4205     ASSERT_NE(controller, nullptr);
4206     TextSpanOptions options;
4207     options.value = INIT_VALUE_1;
4208     controller->AddTextSpan(options);
4209     ImageSpanOptions imageOptions;
4210     imageOptions.image = IMAGE_VALUE;
4211     controller->AddImageSpan(imageOptions);
4212     pattern->textSelector_.Update(0, 6);
4213     auto onDragStart = eventHub->GetOnDragStart();
4214     auto event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
4215     auto dragDropInfo = onDragStart(event, "");
4216     EXPECT_EQ(dragDropInfo.extraInfo, INIT_VALUE_1);
4217     EXPECT_EQ(pattern->textSelector_.GetTextStart(), 0);
4218     EXPECT_EQ(pattern->textSelector_.GetTextEnd(), 6);
4219     EXPECT_EQ(pattern->status_, Status::NONE);
4220     eventHub->FireOnDragMove(event, "");
4221     auto onDragEnd = eventHub->GetOnDragEnd();
4222     onDragEnd(event);
4223     EXPECT_EQ(pattern->status_, Status::NONE);
4224     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4225         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4226     }
4227 }
4228 
4229 /**
4230  * @tc.name: CaretColorTest001
4231  * @tc.desc: test set and get caretColor
4232  * @tc.type: FUNC
4233  */
4234 HWTEST_F(RichEditorTestNg, CaretColorTest001, TestSize.Level1)
4235 {
4236     RichEditorModelNG model;
4237     model.Create();
4238     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
4239     ASSERT_NE(host, nullptr);
4240     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
4241     Color patternCaretColor = richEditorPattern->GetCaretColor();
4242     EXPECT_EQ(patternCaretColor, SYSTEM_CARET_COLOR);
4243     model.SetCaretColor(Color::BLUE);
4244     patternCaretColor = richEditorPattern->GetCaretColor();
4245     EXPECT_EQ(patternCaretColor, Color::BLUE);
4246 }
4247 
4248 /**
4249  * @tc.name: SelectedBackgroundColorTest001
4250  * @tc.desc: test set and get selectedBackgroundColor
4251  * @tc.type: FUNC
4252  */
4253 HWTEST_F(RichEditorTestNg, SelectedBackgroundColorTest001, TestSize.Level1)
4254 {
4255     RichEditorModelNG model;
4256     model.Create();
4257     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
4258     ASSERT_NE(host, nullptr);
4259     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
4260     ASSERT_NE(richEditorPattern, nullptr);
4261     Color patternSelectedBackgroundColor = richEditorPattern->GetSelectedBackgroundColor();
4262     EXPECT_EQ(patternSelectedBackgroundColor, SYSTEM_SELECT_BACKGROUND_COLOR);
4263     model.SetSelectedBackgroundColor(Color::RED);
4264     patternSelectedBackgroundColor = richEditorPattern->GetSelectedBackgroundColor();
4265     auto selectedBackgroundColorResult = Color::RED.ChangeOpacity(DEFAILT_OPACITY);
4266     EXPECT_EQ(patternSelectedBackgroundColor, selectedBackgroundColorResult);
4267 }
4268 
4269 /**
4270  * @tc.name: HandleOnEditChanged001
4271  * @tc.desc: test Get focus edit status is true
4272  * @tc.type: FUNC
4273  */
4274 HWTEST_F(RichEditorTestNg, HandleOnEditChanged001, TestSize.Level1)
4275 {
4276     /* *
4277      * @tc.steps: step1. get richEditor richEditorPattern
4278      */
4279     ASSERT_NE(richEditorNode_, nullptr);
4280 
4281     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4282     ASSERT_NE(richEditorPattern, nullptr);
4283 
4284     /* *
4285      * @tc.steps: step2. Setting Callback Function
4286      */
4287     RichEditorModelNG richEditorModel;
4288     richEditorModel.Create();
__anon814dfc0d1c02(bool value) 4289     richEditorModel.SetOnEditingChange([](bool value) {});
4290 
4291     /* *
4292      * @tc.steps: step3. Get the focus to trigger the callback function and modify the editing status
4293      */
4294     auto richEditorController = richEditorPattern->GetRichEditorController();
4295     ASSERT_NE(richEditorController, nullptr);
4296 
4297     richEditorPattern->HandleFocusEvent();
4298     EXPECT_TRUE(richEditorController->IsEditing());
4299 }
4300 
4301 /**
4302  * @tc.name: HandleOnEditChanged002
4303  * @tc.desc: test Lose focus edit status is true
4304  * @tc.type: FUNC
4305  */
4306 HWTEST_F(RichEditorTestNg, HandleOnEditChanged002, TestSize.Level1)
4307 {
4308     /* *
4309      * @tc.steps: step1. get richEditor richEditorPattern
4310      */
4311     ASSERT_NE(richEditorNode_, nullptr);
4312 
4313     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4314     ASSERT_NE(richEditorPattern, nullptr);
4315 
4316     /* *
4317      * @tc.steps: step2. Setting Callback Function
4318      */
4319     RichEditorModelNG richEditorModel;
4320     richEditorModel.Create();
__anon814dfc0d1d02(bool value) 4321     richEditorModel.SetOnEditingChange([](bool value) {});
4322 
4323     /* *
4324      * @tc.steps: step3. Lose the focus to trigger the callback function and modify the editing status
4325      */
4326     auto richEditorController = richEditorPattern->GetRichEditorController();
4327     ASSERT_NE(richEditorController, nullptr);
4328 
4329     richEditorPattern->HandleBlurEvent();
4330     EXPECT_FALSE(richEditorController->IsEditing());
4331 }
4332 
4333 /**
4334  * @tc.name: HandleOnEditChanged003
4335  * @tc.desc: test Long press edit status is true
4336  * @tc.type: FUNC
4337  */
4338 HWTEST_F(RichEditorTestNg, HandleOnEditChanged003, TestSize.Level1)
4339 {
4340     /* *
4341      * @tc.steps: step1. get richEditor richEditorPattern
4342      */
4343     ASSERT_NE(richEditorNode_, nullptr);
4344 
4345     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4346     ASSERT_NE(richEditorPattern, nullptr);
4347 
4348     /* *
4349      * @tc.steps: step2. Setting Callback Function
4350      */
4351     auto richEditorController = richEditorPattern->GetRichEditorController();
4352     ASSERT_NE(richEditorController, nullptr);
4353 
4354     GestureEvent info;
4355     richEditorPattern->HandleDoubleClickOrLongPress(info);
4356     EXPECT_TRUE(richEditorController->IsEditing());
4357 
4358     RichEditorModelNG richEditorModel;
4359     richEditorModel.Create();
__anon814dfc0d1e02(bool value) 4360     richEditorModel.SetOnEditingChange([](bool value) {});
4361 
4362     /* *
4363      * @tc.steps: step3. Long press to trigger the callback function and modify the editing status
4364      */
4365 
4366     richEditorPattern->HandleDoubleClickOrLongPress(info);
4367     EXPECT_TRUE(richEditorController->IsEditing());
4368 }
4369 
4370 /**
4371  * @tc.name: HandleOnEditChanged004
4372  * @tc.desc: test Click on edit status is true
4373  * @tc.type: FUNC
4374  */
4375 HWTEST_F(RichEditorTestNg, HandleOnEditChanged004, TestSize.Level1)
4376 {
4377     /* *
4378      * @tc.steps: step1. get richEditor richEditorPattern
4379      */
4380     ASSERT_NE(richEditorNode_, nullptr);
4381 
4382     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4383     ASSERT_NE(richEditorPattern, nullptr);
4384 
4385     /* *
4386      * @tc.steps: step2. Setting Callback Function
4387      */
4388     RichEditorModelNG richEditorModel;
4389     richEditorModel.Create();
__anon814dfc0d1f02(bool value) 4390     richEditorModel.SetOnEditingChange([](bool value) {});
4391 
4392     /* *
4393      * @tc.steps: step3. Click on to trigger the callback function and modify the editing status
4394      */
4395     auto richEditorController = richEditorPattern->GetRichEditorController();
4396     ASSERT_NE(richEditorController, nullptr);
4397 
4398     GestureEvent info;
4399     info.SetSourceDevice(SourceType::MOUSE);
4400     richEditorPattern->HandleSingleClickEvent(info);
4401     EXPECT_TRUE(richEditorController->IsEditing());
4402 }
4403 
4404 /**
4405  * @tc.name: HandleOnEditChanged005
4406  * @tc.desc: test mouse release while dragging edit status is true
4407  * @tc.type: FUNC
4408  */
4409 HWTEST_F(RichEditorTestNg, HandleOnEditChanged005, TestSize.Level1)
4410 {
4411     /* *
4412      * @tc.steps: step1. get richEditor richEditorPattern
4413      */
4414     ASSERT_NE(richEditorNode_, nullptr);
4415 
4416     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4417     ASSERT_NE(richEditorPattern, nullptr);
4418 
4419     /* *
4420      * @tc.steps: step2. Setting Callback Function
4421      */
4422     RichEditorModelNG richEditorModel;
4423     richEditorModel.Create();
__anon814dfc0d2002(bool value) 4424     richEditorModel.SetOnEditingChange([](bool value) {});
4425 
4426     /* *
4427      * @tc.steps: step3. mouse release while dragging to trigger the callback function and modify the editing status
4428      */
4429     auto richEditorController = richEditorPattern->GetRichEditorController();
4430     ASSERT_NE(richEditorController, nullptr);
4431 
4432     MouseInfo info;
4433     auto focusHub = richEditorPattern->GetHost()->GetOrCreateFocusHub();
4434     focusHub->currentFocus_ = true;
4435     richEditorPattern->HandleMouseLeftButtonRelease(info);
4436     EXPECT_TRUE(richEditorController->IsEditing());
4437 }
4438 
4439 /**
4440  * @tc.name: StopEditingTest
4441  * @tc.desc: test StopEditing
4442  * @tc.type: FUNC
4443  */
4444 HWTEST_F(RichEditorTestNg, StopEditingTest, TestSize.Level1)
4445 {
4446     /**
4447      * @tc.steps: step1. get richEditor controller
4448      */
4449     ASSERT_NE(richEditorNode_, nullptr);
4450     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4451     ASSERT_NE(richEditorPattern, nullptr);
4452     auto richEditorController = richEditorPattern->GetRichEditorController();
4453     ASSERT_NE(richEditorController, nullptr);
4454     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
4455     ASSERT_NE(focusHub, nullptr);
4456 
4457     /**
4458      * @tc.steps: step2. initalize span properties
4459      */
4460     TextSpanOptions options2;
4461     options2.value = INIT_VALUE_1;
4462 
4463     /**
4464      * @tc.steps: step3. test add span
4465      */
4466     richEditorController->AddTextSpan(options2);
4467     focusHub->RequestFocusImmediately();
4468     EXPECT_TRUE(focusHub->IsCurrentFocus());
4469     richEditorPattern->caretTwinkling_ = true;
4470     richEditorController->StopEditing();
4471 
4472     EXPECT_FALSE(richEditorPattern->caretTwinkling_);
4473 
4474     ClearSpan();
4475 }
4476 
4477 /**
4478  * @tc.name: OnSubmitTest
4479  * @tc.desc: test OnSubmitTest
4480  * @tc.type: FUNC
4481  */
4482 HWTEST_F(RichEditorTestNg, OnSubmitTest, TestSize.Level1)
4483 {
4484     /**
4485      * @tc.steps: step1. get richEditor controller
4486      */
4487     ASSERT_NE(richEditorNode_, nullptr);
4488     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4489     ASSERT_NE(richEditorPattern, nullptr);
4490     auto richEditorController = richEditorPattern->GetRichEditorController();
4491     ASSERT_NE(richEditorController, nullptr);
4492     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
4493     ASSERT_NE(eventHub, nullptr);
4494     /**
4495      * @tc.steps: step2. initalize span properties
4496      */
4497     TextSpanOptions options2;
4498     options2.value = INIT_VALUE_1;
4499 
4500     /**
4501      * @tc.steps: step3. test add span
4502      */
4503     richEditorController->AddTextSpan(options2);
4504 
4505     int count = 0;
4506     TextFieldCommonEvent event2;
__anon814dfc0d2102(int32_t key, NG::TextFieldCommonEvent& event) 4507     auto callback = [&count, &event2](int32_t key, NG::TextFieldCommonEvent& event) {
4508         event2 = event;
4509         if (count > 0) {
4510             event.SetKeepEditable(true);
4511         }
4512         count = count + 1;
4513     };
4514     eventHub->SetOnSubmit(std::move(callback));
4515 
4516     TextInputAction action2 = TextInputAction::NEW_LINE;
4517     bool forceCloseKeyboard = false;
4518     richEditorPattern->PerformAction(action2, forceCloseKeyboard);
4519     EXPECT_EQ(count, 0);
4520 
4521     action2 = TextInputAction::DONE;
4522     richEditorPattern->PerformAction(action2, forceCloseKeyboard);
4523     EXPECT_EQ(count, 1);
4524     richEditorPattern->PerformAction(action2, forceCloseKeyboard);
4525     EXPECT_EQ(count, 2);
4526     ClearSpan();
4527 }
4528 
4529 /**
4530  * @tc.name: SetEnterKeyType
4531  * @tc.desc: test SetEnterKeyType
4532  * @tc.type: FUNC
4533  */
4534 HWTEST_F(RichEditorTestNg, SetEnterKeyType, TestSize.Level1)
4535 {
4536     /**
4537      * @tc.steps: step1. get richEditor controller
4538      */
4539     ASSERT_NE(richEditorNode_, nullptr);
4540     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4541     ASSERT_NE(richEditorPattern, nullptr);
4542 
4543     RichEditorModelNG richEditorModel;
4544     richEditorModel.Create();
4545     richEditorModel.SetEnterKeyType(TextInputAction::NEW_LINE);
4546     richEditorNode_->MarkModifyDone();
4547     EXPECT_EQ(richEditorPattern->GetTextInputActionValue(richEditorPattern->GetDefaultTextInputAction()),
4548         TextInputAction::NEW_LINE);
4549     richEditorModel.SetEnterKeyType(TextInputAction::UNSPECIFIED);
4550     richEditorNode_->MarkModifyDone();
4551     EXPECT_EQ(richEditorPattern->GetTextInputActionValue(richEditorPattern->GetDefaultTextInputAction()),
4552         TextInputAction::NEW_LINE);
4553     ClearSpan();
4554 }
4555 
4556 /**
4557  * @tc.name: onIMEInputComplete
4558  * @tc.desc: test onIMEInputComplete
4559  * @tc.type: FUNC
4560  */
4561 HWTEST_F(RichEditorTestNg, onIMEInputComplete002, TestSize.Level1)
4562 {
4563     /**
4564      * @tc.steps: step1. get richEditor controller
4565      */
4566     ASSERT_NE(richEditorNode_, nullptr);
4567     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4568     ASSERT_NE(richEditorPattern, nullptr);
4569     auto richEditorController = richEditorPattern->GetRichEditorController();
4570     ASSERT_NE(richEditorController, nullptr);
4571     /**
4572      * @tc.steps: step2. initalize span properties
4573      */
4574     TextStyle style;
4575     style.SetLineHeight(LINE_HEIGHT_VALUE);
4576     style.SetLetterSpacing(LETTER_SPACING);
4577     style.SetFontFeatures(TEXT_FONTFEATURE);
4578     TextSpanOptions options;
4579     options.value = INIT_VALUE_1;
4580     options.style = style;
4581     richEditorController->AddTextSpan(options);
4582     /**
4583      * @tc.steps: step3. add text span
4584      */
4585     AddSpan(INIT_VALUE_1);
4586     auto info = richEditorController->GetSpansInfo(1, 5);
4587     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4588     EXPECT_EQ(textStyle1.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4589     EXPECT_EQ(textStyle1.letterSpacing, LETTER_SPACING.ConvertToVp());
4590     for (const auto& pair : textStyle1.fontFeature) {
4591         EXPECT_EQ(pair.first, "subs");
4592         EXPECT_EQ(pair.second, 1);
4593     }
4594     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
4595     ASSERT_NE(eventHub, nullptr);
4596     TextStyleResult textStyle;
__anon814dfc0d2202(const RichEditorAbstractSpanResult& info) 4597     auto func = [&textStyle](const RichEditorAbstractSpanResult& info) { textStyle = info.GetTextStyle(); };
4598     eventHub->SetOnIMEInputComplete(std::move(func));
4599     auto it1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
4600     richEditorPattern->AfterIMEInsertValue(it1, 1, false);
4601     EXPECT_EQ(textStyle.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4602     EXPECT_EQ(textStyle.letterSpacing, LETTER_SPACING.ConvertToVp());
4603     for (const auto& pair : textStyle1.fontFeature) {
4604         EXPECT_EQ(pair.first, "subs");
4605         EXPECT_EQ(pair.second, 1);
4606     }
4607     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4608         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4609     }
4610     ClearSpan();
4611 }
4612 
4613 /**
4614  * @tc.name: onIMEInputComplete
4615  * @tc.desc: test onIMEInputComplete
4616  * @tc.type: FUNC
4617  */
4618 HWTEST_F(RichEditorTestNg, onIMEInputComplete003, TestSize.Level1)
4619 {
4620     /**
4621      * @tc.steps: step1. get richEditor controller
4622      */
4623     ASSERT_NE(richEditorNode_, nullptr);
4624     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4625     ASSERT_NE(richEditorPattern, nullptr);
4626     auto richEditorController = richEditorPattern->GetRichEditorController();
4627     ASSERT_NE(richEditorController, nullptr);
4628     /**
4629      * @tc.steps: step2. initalize span properties
4630      */
4631     TextStyle style;
4632     style.SetFontFeatures(TEXT_FONTFEATURE_2);
4633     TextSpanOptions options;
4634     options.value = INIT_VALUE_1;
4635     options.style = style;
4636     richEditorController->AddTextSpan(options);
4637     /**
4638      * @tc.steps: step3. add text span
4639      */
4640     auto info = richEditorController->GetSpansInfo(1, 5);
4641     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4642     for (const auto& pair : textStyle1.fontFeature) {
4643         EXPECT_EQ(pair.first, "subs");
4644         EXPECT_EQ(pair.second, 0);
4645     }
4646     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
4647     ASSERT_NE(eventHub, nullptr);
4648     TextStyleResult textStyle;
__anon814dfc0d2302(const RichEditorAbstractSpanResult& info) 4649     auto func = [&textStyle](const RichEditorAbstractSpanResult& info) { textStyle = info.GetTextStyle(); };
4650     eventHub->SetOnIMEInputComplete(std::move(func));
4651     auto it1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
4652     richEditorPattern->AfterIMEInsertValue(it1, 1, false);
4653     for (const auto& pair : textStyle1.fontFeature) {
4654         EXPECT_EQ(pair.first, "subs");
4655         EXPECT_EQ(pair.second, 0);
4656     }
4657     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4658         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4659     }
4660     ClearSpan();
4661 }
4662 
4663 /**
4664  * @tc.name: UpdateTextStyle
4665  * @tc.desc: test update span style
4666  * @tc.type: FUNC
4667  */
4668 HWTEST_F(RichEditorTestNg, UpdateTextStyle, TestSize.Level1)
4669 {
4670     ASSERT_NE(richEditorNode_, nullptr);
4671     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4672     ASSERT_NE(richEditorPattern, nullptr);
4673     auto richEditorController = richEditorPattern->GetRichEditorController();
4674     ASSERT_NE(richEditorController, nullptr);
4675     AddSpan(INIT_VALUE_1);
4676     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
4677     TextStyle textStyle;
4678     ImageSpanAttribute imageStyle;
4679     textStyle.SetFontFeatures(TEXT_FONTFEATURE);
4680     textStyle.SetLineHeight(LINE_HEIGHT_VALUE);
4681     textStyle.SetLetterSpacing(LETTER_SPACING);
4682     struct UpdateSpanStyle updateSpanStyle;
4683     updateSpanStyle.updateLineHeight = LINE_HEIGHT_VALUE;
4684     updateSpanStyle.updateLetterSpacing = LETTER_SPACING;
4685     updateSpanStyle.updateFontFeature = TEXT_FONTFEATURE;
4686 
4687     richEditorPattern->UpdateTextStyle(newSpan1, updateSpanStyle, textStyle);
4688     ASSERT_NE(newSpan1, nullptr);
4689     EXPECT_EQ(newSpan1->GetLineHeight(), LINE_HEIGHT_VALUE);
4690     EXPECT_EQ(newSpan1->GetLetterSpacing(), LETTER_SPACING);
4691     for (const auto& pair : *newSpan1->GetFontFeature()) {
4692         EXPECT_EQ(pair.first, "subs");
4693         EXPECT_EQ(pair.second, 1);
4694     }
4695     ClearSpan();
4696 }
4697 
4698 /**
4699  * @tc.name: UpdateTextStyle
4700  * @tc.desc: test update span style
4701  * @tc.type: FUNC
4702  */
4703 HWTEST_F(RichEditorTestNg, UpdateTextStyle2, TestSize.Level1)
4704 {
4705     ASSERT_NE(richEditorNode_, nullptr);
4706     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4707     ASSERT_NE(richEditorPattern, nullptr);
4708     auto richEditorController = richEditorPattern->GetRichEditorController();
4709     ASSERT_NE(richEditorController, nullptr);
4710     AddSpan(INIT_VALUE_1);
4711     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
4712     TextStyle textStyle;
4713     ImageSpanAttribute imageStyle;
4714     textStyle.SetFontFeatures(TEXT_FONTFEATURE_2);
4715     struct UpdateSpanStyle updateSpanStyle;
4716     updateSpanStyle.updateFontFeature = TEXT_FONTFEATURE;
4717     richEditorPattern->UpdateTextStyle(newSpan1, updateSpanStyle, textStyle);
4718     ASSERT_NE(newSpan1, nullptr);
4719     for (const auto& pair : *newSpan1->GetFontFeature()) {
4720         EXPECT_EQ(pair.first, "subs");
4721         EXPECT_EQ(pair.second, 0);
4722     }
4723     ClearSpan();
4724 }
4725 
4726 /**
4727  * @tc.name: SetOnSelect
4728  * @tc.desc: test set on select
4729  * @tc.type: FUNC
4730  */
4731 HWTEST_F(RichEditorTestNg, SetOnSelect, TestSize.Level1)
4732 {
4733     ASSERT_NE(richEditorNode_, nullptr);
4734     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4735     ASSERT_NE(richEditorPattern, nullptr);
4736     auto richEditorController = richEditorPattern->GetRichEditorController();
4737     ASSERT_NE(richEditorController, nullptr);
4738     TextStyle style;
4739     style.SetLineHeight(LINE_HEIGHT_VALUE);
4740     style.SetLetterSpacing(LETTER_SPACING);
4741     style.SetFontFeatures(TEXT_FONTFEATURE);
4742     TextSpanOptions options;
4743     options.value = INIT_VALUE_1;
4744     options.style = style;
4745     richEditorController->AddTextSpan(options);
4746     AddSpan(INIT_VALUE_1);
4747     auto info = richEditorController->GetSpansInfo(1, 5);
4748     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4749     EXPECT_EQ(textStyle1.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4750     EXPECT_EQ(textStyle1.letterSpacing, LETTER_SPACING.ConvertToVp());
4751     RichEditorModelNG richEditorModel;
4752     richEditorModel.Create();
__anon814dfc0d2402(const BaseEventInfo* info) 4753     auto func = [](const BaseEventInfo* info) { testOnSelect = 1; };
4754     richEditorModel.SetOnSelect(std::move(func));
4755     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
4756     ASSERT_NE(eventHub, nullptr);
4757     SelectionInfo selection;
4758     eventHub->FireOnSelect(&selection);
4759     EXPECT_EQ(testOnSelect, 1);
4760     EXPECT_EQ(textStyle1.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4761     EXPECT_EQ(textStyle1.letterSpacing, LETTER_SPACING.ConvertToVp());
4762     for (const auto& pair : textStyle1.fontFeature) {
4763         EXPECT_EQ(pair.first, "subs");
4764         EXPECT_EQ(pair.second, 1);
4765     }
4766     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4767         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4768     }
4769     ClearSpan();
4770 }
4771 
4772 /**
4773  * @tc.name: SetOnSelect
4774  * @tc.desc: test set on select
4775  * @tc.type: FUNC
4776  */
4777 HWTEST_F(RichEditorTestNg, SetOnSelect2, TestSize.Level1)
4778 {
4779     ASSERT_NE(richEditorNode_, nullptr);
4780     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4781     ASSERT_NE(richEditorPattern, nullptr);
4782     auto richEditorController = richEditorPattern->GetRichEditorController();
4783     ASSERT_NE(richEditorController, nullptr);
4784     TextStyle style;
4785     style.SetFontFeatures(TEXT_FONTFEATURE_2);
4786     TextSpanOptions options;
4787     options.value = INIT_VALUE_1;
4788     options.style = style;
4789     richEditorController->AddTextSpan(options);
4790     auto info = richEditorController->GetSpansInfo(1, 5);
4791     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4792     RichEditorModelNG richEditorModel;
4793     richEditorModel.Create();
__anon814dfc0d2502(const BaseEventInfo* info) 4794     auto func = [](const BaseEventInfo* info) { testOnSelect = 1; };
4795     richEditorModel.SetOnSelect(std::move(func));
4796     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
4797     ASSERT_NE(eventHub, nullptr);
4798     SelectionInfo selection;
4799     eventHub->FireOnSelect(&selection);
4800     EXPECT_EQ(testOnSelect, 1);
4801     for (const auto& pair : textStyle1.fontFeature) {
4802         EXPECT_EQ(pair.first, "subs");
4803         EXPECT_EQ(pair.second, 0);
4804     }
4805     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
4806         ViewStackProcessor::GetInstance()->elementsStack_.pop();
4807     }
4808     ClearSpan();
4809 }
4810 
4811 /**
4812  * @tc.name: SetTypingStyle
4813  * @tc.desc: test Typing Style
4814  * @tc.type: FUNC
4815  */
4816 HWTEST_F(RichEditorTestNg, SetTypingStyle, TestSize.Level1)
4817 {
4818     /**
4819      * @tc.steps: step1. get richEditor controller
4820      */
4821     ASSERT_NE(richEditorNode_, nullptr);
4822     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4823     ASSERT_NE(richEditorPattern, nullptr);
4824     auto richEditorController = richEditorPattern->GetRichEditorController();
4825     ASSERT_NE(richEditorController, nullptr);
4826     TextStyle style;
4827     style.SetLineHeight(LINE_HEIGHT_VALUE);
4828     style.SetLetterSpacing(LETTER_SPACING);
4829     style.SetFontFeatures(TEXT_FONTFEATURE);
4830     TextSpanOptions options;
4831     options.value = INIT_VALUE_1;
4832     options.style = style;
4833     richEditorController->AddTextSpan(options);
4834     AddSpan(INIT_VALUE_1);
4835     auto info = richEditorController->GetSpansInfo(1, 5);
4836     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4837     UpdateSpanStyle typingStyle;
4838     richEditorPattern->SetTypingStyle(typingStyle, style);
4839     TextSpanOptions options1;
4840     options1.style = richEditorPattern->typingTextStyle_;
4841     AddSpan(INIT_VALUE_1);
4842     auto info1 = richEditorController->GetSpansInfo(1, 5);
4843     TextStyleResult textStyle2 = info1.selection_.resultObjects.front().textStyle;
4844     EXPECT_EQ(textStyle2.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4845     EXPECT_EQ(textStyle2.letterSpacing, LETTER_SPACING.ConvertToVp());
4846     for (const auto& pair : textStyle1.fontFeature) {
4847         EXPECT_EQ(pair.first, "subs");
4848         EXPECT_EQ(pair.second, 1);
4849     }
4850     ClearSpan();
4851 }
4852 
4853 /**
4854  * @tc.name: SetTypingStyle
4855  * @tc.desc: test Typing Style
4856  * @tc.type: FUNC
4857  */
4858 HWTEST_F(RichEditorTestNg, SetTypingStyle2, TestSize.Level1)
4859 {
4860     /**
4861      * @tc.steps: step1. get richEditor controller
4862      */
4863     ASSERT_NE(richEditorNode_, nullptr);
4864     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4865     ASSERT_NE(richEditorPattern, nullptr);
4866     auto richEditorController = richEditorPattern->GetRichEditorController();
4867     ASSERT_NE(richEditorController, nullptr);
4868     TextStyle style;
4869     style.SetFontFeatures(TEXT_FONTFEATURE_2);
4870     TextSpanOptions options;
4871     options.value = INIT_VALUE_1;
4872     options.style = style;
4873     richEditorController->AddTextSpan(options);
4874     auto info = richEditorController->GetSpansInfo(1, 5);
4875     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4876     UpdateSpanStyle typingStyle;
4877     richEditorPattern->SetTypingStyle(typingStyle, style);
4878     TextSpanOptions options1;
4879     options1.style = richEditorPattern->typingTextStyle_;
4880     auto info1 = richEditorController->GetSpansInfo(1, 5);
4881     TextStyleResult textStyle2 = info1.selection_.resultObjects.front().textStyle;
4882     for (const auto& pair : textStyle1.fontFeature) {
4883         EXPECT_EQ(pair.first, "subs");
4884         EXPECT_EQ(pair.second, 0);
4885     }
4886     ClearSpan();
4887 }
4888 
4889 /**
4890  * @tc.name: SetOnSelect
4891  * @tc.desc: test Set On Select
4892  * @tc.type: FUNC
4893  */
4894 HWTEST_F(RichEditorTestNg, SetOnSelect003, TestSize.Level1)
4895 {
4896     /**
4897      * @tc.steps: step1. get richEditor controller
4898      */
4899     ASSERT_NE(richEditorNode_, nullptr);
4900     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4901     ASSERT_NE(richEditorPattern, nullptr);
4902     auto richEditorController = richEditorPattern->GetRichEditorController();
4903     ASSERT_NE(richEditorController, nullptr);
4904     TextStyle style;
4905     style.SetLineHeight(LINE_HEIGHT_VALUE);
4906     style.SetLetterSpacing(LETTER_SPACING);
4907     style.SetFontFeatures(TEXT_FONTFEATURE);
4908     TextSpanOptions options;
4909     options.value = INIT_VALUE_1;
4910     options.style = style;
4911     richEditorController->AddTextSpan(options);
4912     AddSpan(INIT_VALUE_1);
4913     auto info = richEditorController->GetSpansInfo(1, 5);
4914     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4915     RichEditorModelNG richEditorModel;
4916     richEditorModel.Create();
4917     auto spanNode = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
__anon814dfc0d2602(const BaseEventInfo* info) 4918     auto func = [](const BaseEventInfo* info) { testOnSelect = 1; };
4919     richEditorModel.SetOnSelect(std::move(func));
4920     EXPECT_EQ(textStyle1.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4921     EXPECT_EQ(textStyle1.letterSpacing, LETTER_SPACING.ConvertToVp());
4922     for (const auto& pair : textStyle1.fontFeature) {
4923         EXPECT_EQ(pair.first, "subs");
4924         EXPECT_EQ(pair.second, 1);
4925     }
4926     ClearSpan();
4927 }
4928 
4929 /**
4930  * @tc.name: SetOnSelect
4931  * @tc.desc: test Set On Select
4932  * @tc.type: FUNC
4933  */
4934 HWTEST_F(RichEditorTestNg, SetOnSelect004, TestSize.Level1)
4935 {
4936     /**
4937      * @tc.steps: step1. get richEditor controller
4938      */
4939     ASSERT_NE(richEditorNode_, nullptr);
4940     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4941     ASSERT_NE(richEditorPattern, nullptr);
4942     auto richEditorController = richEditorPattern->GetRichEditorController();
4943     ASSERT_NE(richEditorController, nullptr);
4944     TextStyle style;
4945     style.SetFontFeatures(TEXT_FONTFEATURE_2);
4946     TextSpanOptions options;
4947     options.value = INIT_VALUE_1;
4948     options.style = style;
4949     richEditorController->AddTextSpan(options);
4950     auto info = richEditorController->GetSpansInfo(1, 5);
4951     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
4952     RichEditorModelNG richEditorModel;
4953     richEditorModel.Create();
4954     auto spanNode = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
__anon814dfc0d2702(const BaseEventInfo* info) 4955     auto func = [](const BaseEventInfo* info) { testOnSelect = 1; };
4956     richEditorModel.SetOnSelect(std::move(func));
4957     for (const auto& pair : textStyle1.fontFeature) {
4958         EXPECT_EQ(pair.first, "subs");
4959         EXPECT_EQ(pair.second, 0);
4960     }
4961     ClearSpan();
4962 }
4963 
4964 /**
4965  * @tc.name: SetSelection
4966  * @tc.desc: test Set Selection
4967  * @tc.type: FUNC
4968  */
4969 HWTEST_F(RichEditorTestNg, SetSelection, TestSize.Level1)
4970 {
4971     ASSERT_NE(richEditorNode_, nullptr);
4972     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
4973     ASSERT_NE(richEditorPattern, nullptr);
4974     auto richEditorController = richEditorPattern->GetRichEditorController();
4975     ASSERT_NE(richEditorController, nullptr);
4976     TextStyle style;
4977     style.SetLineHeight(LINE_HEIGHT_VALUE);
4978     style.SetLetterSpacing(LETTER_SPACING);
4979     style.SetFontFeatures(TEXT_FONTFEATURE);
4980     TextSpanOptions options;
4981     options.value = INIT_VALUE_1;
4982     options.style = style;
4983     richEditorController->AddTextSpan(options);
4984     AddSpan(INIT_VALUE_1);
4985     richEditorPattern->SetSelection(1, 3);
4986     auto info1 = richEditorController->GetSpansInfo(1, 2);
4987     EXPECT_EQ(info1.selection_.resultObjects.front().textStyle.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
4988     EXPECT_EQ(info1.selection_.resultObjects.front().textStyle.letterSpacing, LETTER_SPACING.ConvertToVp());
4989     for (const auto& pair : info1.selection_.resultObjects.front().textStyle.fontFeature) {
4990         EXPECT_EQ(pair.first, "subs");
4991         EXPECT_EQ(pair.second, 1);
4992     }
4993     ClearSpan();
4994 }
4995 
4996 /**
4997  * @tc.name: SetSelection2
4998  * @tc.desc: test Set Selection
4999  * @tc.type: FUNC
5000  */
5001 HWTEST_F(RichEditorTestNg, SetSelection2, TestSize.Level1)
5002 {
5003     ASSERT_NE(richEditorNode_, nullptr);
5004     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
5005     ASSERT_NE(richEditorPattern, nullptr);
5006     auto richEditorController = richEditorPattern->GetRichEditorController();
5007     ASSERT_NE(richEditorController, nullptr);
5008     TextStyle style;
5009     style.SetFontFeatures(TEXT_FONTFEATURE_2);
5010     TextSpanOptions options;
5011     options.value = INIT_VALUE_1;
5012     options.style = style;
5013     richEditorController->AddTextSpan(options);
5014     AddSpan(INIT_VALUE_1);
5015     richEditorPattern->SetSelection(1, 3);
5016     auto info1 = richEditorController->GetSpansInfo(1, 2);
5017     for (const auto& pair : info1.selection_.resultObjects.front().textStyle.fontFeature) {
5018         EXPECT_EQ(pair.first, "subs");
5019         EXPECT_EQ(pair.second, 0);
5020     }
5021     ClearSpan();
5022 }
5023 
5024 /**
5025  * @tc.name: GetTextSpansInfo
5026  * @tc.desc: test get paragraphStyle
5027  * @tc.type: FUNC
5028  */
5029 HWTEST_F(RichEditorTestNg, GetTextSpansInfo, TestSize.Level1)
5030 {
5031     /**
5032      * @tc.steps: step1. get richEditor controller
5033      */
5034     ASSERT_NE(richEditorNode_, nullptr);
5035     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
5036     ASSERT_NE(richEditorPattern, nullptr);
5037     auto richEditorController = richEditorPattern->GetRichEditorController();
5038     ASSERT_NE(richEditorController, nullptr);
5039 
5040     /**
5041      * @tc.steps: step2. initalize span properties
5042      */
5043     TextSpanOptions options;
5044     options.value = INIT_VALUE_1;
5045 
5046     /**
5047      * @tc.steps: step3. test add span
5048      */
5049     richEditorController->AddTextSpan(options);
5050 
5051     struct UpdateParagraphStyle style1;
5052     style1.textAlign = TextAlign::END;
5053     style1.leadingMargin = std::make_optional<NG::LeadingMargin>();
5054     style1.leadingMargin->size = LeadingMarginSize(Dimension(5.0), Dimension(10.0));
5055     richEditorPattern->UpdateParagraphStyle(0, 6, style1);
5056 
5057     auto info = richEditorController->GetSpansInfo(0, 6);
5058     EXPECT_EQ(info.selection_.resultObjects.size(), 1);
5059     auto valueString = info.selection_.resultObjects.begin()->valueString;
5060     auto textStyle = info.selection_.resultObjects.begin()->textStyle;
5061 
5062     EXPECT_EQ(textStyle.textAlign, int(TextAlign::END));
5063     EXPECT_EQ(textStyle.leadingMarginSize[0], "5.00px");
5064     EXPECT_EQ(textStyle.leadingMarginSize[1], "10.00px");
5065 
5066     ClearSpan();
5067 }
5068 
5069 /**
5070  * @tc.name: GetImageSpansInfo
5071  * @tc.desc: test image span layoutStyle
5072  * @tc.type: FUNC
5073  */
5074 HWTEST_F(RichEditorTestNg, GetImageSpansInfo, TestSize.Level1)
5075 {
5076     /**
5077      * @tc.steps: step1. get richEditor controller
5078      */
5079     ASSERT_NE(richEditorNode_, nullptr);
5080     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
5081     ASSERT_NE(richEditorPattern, nullptr);
5082     auto richEditorController = richEditorPattern->GetRichEditorController();
5083     ASSERT_NE(richEditorController, nullptr);
5084 
5085     /**
5086      * @tc.steps: step2. initalize span properties
5087      */
5088     ImageSpanOptions options;
5089     options.image = IMAGE_VALUE;
5090     std::optional<Ace::NG::MarginProperty> marginProp = std::nullopt;
5091     std::optional<Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt;
5092     marginProp = { CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC };
5093     borderRadius = { CALC_TEST, CALC_TEST, CALC_TEST, CALC_TEST };
5094     ImageSpanAttribute imageStyle;
5095     imageStyle.marginProp = marginProp;
5096     imageStyle.borderRadius = borderRadius;
5097     options.imageAttribute = imageStyle;
5098 
5099     /**
5100      * @tc.steps: step3. test add span
5101      */
5102     richEditorController->AddImageSpan(options);
5103     auto info = richEditorController->GetSpansInfo(0, 1);
5104     EXPECT_EQ(info.selection_.resultObjects.size(), 1);
5105     auto imageStyleout = info.selection_.resultObjects.begin()->imageStyle;
5106     EXPECT_EQ(imageStyleout.borderRadius,
5107         "{\"topLeft\":\"10.00px\",\"topRight\":\"10.00px\",\"bottomLeft\":\"10.00px\",\"bottomRight\":\"10.00px\"}");
5108     EXPECT_EQ(imageStyleout.margin, "left: [10.00px]right: [10.00px]top: [10.00px]bottom: [10.00px]");
5109     ClearSpan();
5110 }
5111 
5112 /**
5113  * @tc.name: DeleteValueSetTextSpan
5114  * @tc.desc: test add delete text span
5115  * @tc.type: FUNC
5116  */
5117 HWTEST_F(RichEditorTestNg, DeleteValueSetTextSpan, TestSize.Level1)
5118 {
5119     /**
5120      * @tc.steps: step1. get richEditor controller
5121      */
5122     ASSERT_NE(richEditorNode_, nullptr);
5123     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
5124     ASSERT_NE(richEditorPattern, nullptr);
5125     auto richEditorController = richEditorPattern->GetRichEditorController();
5126     ASSERT_NE(richEditorController, nullptr);
5127 
5128     /**
5129      * @tc.steps: step2. test add span
5130      */
5131     AddSpan(INIT_VALUE_1);
5132     struct UpdateParagraphStyle style1;
5133     style1.textAlign = TextAlign::END;
5134     style1.leadingMargin = std::make_optional<NG::LeadingMargin>();
5135     style1.leadingMargin->size = LeadingMarginSize(Dimension(5.0), Dimension(10.0));
5136     richEditorPattern->UpdateParagraphStyle(0, 6, style1);
5137     auto info = richEditorController->GetSpansInfo(0, 6);
5138     EXPECT_EQ(info.selection_.resultObjects.size(), 1);
5139 
5140     auto it = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
5141     auto spanItem = it->GetSpanItem();
5142     spanItem->position = 0;
5143     spanItem->textStyle_ = TextStyle();
5144     spanItem->textStyle_.value().fontFamilies_.push_back("test1");
5145     RichEditorAbstractSpanResult spanResult;
5146     spanResult.SetSpanIndex(0);
5147     richEditorPattern->DeleteValueSetTextSpan(spanItem, 0, 1, spanResult);
5148 
5149     EXPECT_EQ(spanResult.GetTextStyle().textAlign, int(TextAlign::END));
5150     EXPECT_EQ(spanResult.GetTextStyle().leadingMarginSize[0], "5.00px");
5151     EXPECT_EQ(spanResult.GetTextStyle().leadingMarginSize[1], "10.00px");
5152 
5153     ClearSpan();
5154 }
5155 
5156 /**
5157  * @tc.name: onIMEInputComplete
5158  * @tc.desc: test onIMEInputComplete
5159  * @tc.type: FUNC
5160  */
5161 HWTEST_F(RichEditorTestNg, onIMEInputComplete, TestSize.Level1)
5162 {
5163     /**
5164      * @tc.steps: step1. get richEditor controller
5165      */
5166     ASSERT_NE(richEditorNode_, nullptr);
5167     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
5168     ASSERT_NE(richEditorPattern, nullptr);
5169     auto richEditorController = richEditorPattern->GetRichEditorController();
5170     ASSERT_NE(richEditorController, nullptr);
5171 
5172     /**
5173      * @tc.steps: step2. add text span
5174      */
5175     AddSpan(INIT_VALUE_1);
5176     struct UpdateParagraphStyle style1;
5177     style1.textAlign = TextAlign::END;
5178     style1.leadingMargin = std::make_optional<NG::LeadingMargin>();
5179     style1.leadingMargin->size = LeadingMarginSize(Dimension(5.0), Dimension(10.0));
5180     richEditorPattern->UpdateParagraphStyle(0, 6, style1);
5181     auto info = richEditorController->GetSpansInfo(0, 6);
5182     EXPECT_EQ(info.selection_.resultObjects.size(), 1);
5183 
5184     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5185     ASSERT_NE(eventHub, nullptr);
5186     TextStyleResult textStyle;
__anon814dfc0d2802(const RichEditorAbstractSpanResult& info) 5187     auto func = [&textStyle](const RichEditorAbstractSpanResult& info) { textStyle = info.GetTextStyle(); };
5188     eventHub->SetOnIMEInputComplete(std::move(func));
5189     auto it1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
5190     richEditorPattern->AfterIMEInsertValue(it1, 1, false);
5191     EXPECT_EQ(textStyle.textAlign, int(TextAlign::END));
5192     EXPECT_EQ(textStyle.leadingMarginSize[0], "5.00px");
5193     EXPECT_EQ(textStyle.leadingMarginSize[1], "10.00px");
5194     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
5195         ViewStackProcessor::GetInstance()->elementsStack_.pop();
5196     }
5197 
5198     ClearSpan();
5199 }
5200 
5201 /**
5202  * @tc.name: DeleteValueSetImageSpan
5203  * @tc.desc: test delete imagespan
5204  * @tc.type: FUNC
5205  */
5206 HWTEST_F(RichEditorTestNg, DeleteValueSetImageSpan, TestSize.Level1)
5207 {
5208     /**
5209      * @tc.steps: step1. get richEditor controller
5210      */
5211     ASSERT_NE(richEditorNode_, nullptr);
5212     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
5213     ASSERT_NE(richEditorPattern, nullptr);
5214     auto richEditorController = richEditorPattern->GetRichEditorController();
5215     ASSERT_NE(richEditorController, nullptr);
5216 
5217     /**
5218      * @tc.steps: step2. initalize span properties
5219      */
5220     ImageSpanOptions options;
5221     options.image = IMAGE_VALUE;
5222     std::optional<Ace::NG::MarginProperty> marginProp = std::nullopt;
5223     std::optional<Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt;
5224     marginProp = { CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC };
5225     borderRadius = { CALC_TEST, CALC_TEST, CALC_TEST, CALC_TEST };
5226     ImageSpanAttribute imageStyle;
5227     imageStyle.marginProp = marginProp;
5228     imageStyle.borderRadius = borderRadius;
5229     options.imageAttribute = imageStyle;
5230 
5231     /**
5232      * @tc.steps: step3. test delete image span
5233      */
5234     richEditorController->AddImageSpan(options);
5235     RichEditorAbstractSpanResult spanResult;
5236     spanResult.SetSpanIndex(0);
5237     auto spanItem = richEditorPattern->spans_.front();
5238     richEditorPattern->DeleteValueSetImageSpan(spanItem, spanResult);
5239     EXPECT_EQ(spanResult.GetMargin(), "left: [10.00px]right: [10.00px]top: [10.00px]bottom: [10.00px]");
5240     EXPECT_EQ(spanResult.GetBorderRadius(),
5241         "{\"topLeft\":\"10.00px\",\"topRight\":\"10.00px\",\"bottomLeft\":\"10.00px\",\"bottomRight\":\"10.00px\"}");
5242 
5243     ClearSpan();
5244 }
5245 
5246 /**
5247  * @tc.name: HandleOnCut002
5248  * @tc.desc: test InsertValueByPaste
5249  * @tc.type: FUNC
5250  */
5251 HWTEST_F(RichEditorTestNg, HandleOnCut002, TestSize.Level1)
5252 {
5253     /**
5254      * @tc.steps: step1. init callback
5255      */
5256     RichEditorModelNG richEditorModel;
5257     richEditorModel.Create();
5258     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5259     ASSERT_NE(host, nullptr);
5260     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5261     ASSERT_NE(richEditorPattern, nullptr);
5262     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5263     ASSERT_NE(eventHub, nullptr);
5264     bool isEventCalled = false;
__anon814dfc0d2902(NG::TextCommonEvent& event) 5265     auto onCutWithEvent = [&isEventCalled](NG::TextCommonEvent& event) { isEventCalled = true; };
5266     richEditorModel.SetOnCut(std::move(onCutWithEvent));
5267 
5268     /**
5269      * @tc.steps: step2. call the callback function
5270      * @tc.expected: UpdateType_ and isEventCalled is valid
5271      */
5272     richEditorPattern->copyOption_ = CopyOptions::InApp;
5273     richEditorPattern->caretPosition_ = 0;
5274     richEditorPattern->textSelector_.baseOffset = 0;
5275     richEditorPattern->textSelector_.destinationOffset = 1;
5276     richEditorPattern->caretUpdateType_ = CaretUpdateType::PRESSED;
5277     richEditorPattern->HandleOnCut();
5278     EXPECT_EQ(richEditorPattern->caretUpdateType_, CaretUpdateType::NONE);
5279     EXPECT_EQ(isEventCalled, true);
5280 }
5281 
5282 /**
5283  * @tc.name: HandleOnCut003
5284  * @tc.desc: test InsertValueByPaste
5285  * @tc.type: FUNC
5286  */
5287 HWTEST_F(RichEditorTestNg, HandleOnCut003, TestSize.Level1)
5288 {
5289     /**
5290      * @tc.steps: step1. init callback
5291      */
5292     RichEditorModelNG richEditorModel;
5293     richEditorModel.Create();
5294     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5295     ASSERT_NE(host, nullptr);
5296     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5297     ASSERT_NE(richEditorPattern, nullptr);
5298     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5299     ASSERT_NE(eventHub, nullptr);
5300     bool isEventCalled = false;
__anon814dfc0d2a02(NG::TextCommonEvent& event) 5301     auto onCutWithEvent = [&isEventCalled](NG::TextCommonEvent& event) {
5302         isEventCalled = true;
5303         event.SetPreventDefault(true);
5304     };
5305     richEditorModel.SetOnCut(std::move(onCutWithEvent));
5306 
5307     /**
5308      * @tc.steps: step2. call the callback function
5309      * @tc.expected: when PreventDefault is true, UpdateType_ and isEventCalled is valid
5310      */
5311     richEditorPattern->copyOption_ = CopyOptions::InApp;
5312     richEditorPattern->caretPosition_ = 0;
5313     richEditorPattern->textSelector_.baseOffset = 0;
5314     richEditorPattern->textSelector_.destinationOffset = 1;
5315     richEditorPattern->caretUpdateType_ = CaretUpdateType::PRESSED;
5316     richEditorPattern->HandleOnCut();
5317     EXPECT_EQ(richEditorPattern->caretUpdateType_, CaretUpdateType::PRESSED);
5318     EXPECT_EQ(isEventCalled, true);
5319 }
5320 
5321 /**
5322  * @tc.name: HandleOnCopy002
5323  * @tc.desc: test InsertValueByPaste
5324  * @tc.type: FUNC
5325  */
5326 HWTEST_F(RichEditorTestNg, HandleOnCopy002, TestSize.Level1)
5327 {
5328     /**
5329      * @tc.steps: step1. init callback
5330      */
5331     RichEditorModelNG richEditorModel;
5332     richEditorModel.Create();
5333     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5334     ASSERT_NE(host, nullptr);
5335     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5336     ASSERT_NE(richEditorPattern, nullptr);
5337     auto pipeline = MockPipelineContext::GetCurrent();
5338     auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
5339     richEditorPattern->clipboard_ = clipboard;
5340     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5341     ASSERT_NE(eventHub, nullptr);
5342     bool isEventCalled = false;
__anon814dfc0d2b02(NG::TextCommonEvent& event) 5343     auto onCopyWithEvent = [&isEventCalled](NG::TextCommonEvent& event) { isEventCalled = true; };
5344     richEditorModel.SetOnCopy(std::move(onCopyWithEvent));
5345 
5346     /**
5347      * @tc.steps: step2. call the callback function
5348      * @tc.expected: UpdateType_ and isEventCalled is valid
5349      */
5350     richEditorPattern->copyOption_ = CopyOptions::InApp;
5351     richEditorPattern->caretPosition_ = 0;
5352     richEditorPattern->textSelector_.baseOffset = 0;
5353     richEditorPattern->textSelector_.destinationOffset = 1;
5354     richEditorPattern->caretUpdateType_ = CaretUpdateType::PRESSED;
5355     richEditorPattern->HandleOnCopy();
5356     EXPECT_EQ(richEditorPattern->caretUpdateType_, CaretUpdateType::NONE);
5357     EXPECT_EQ(isEventCalled, true);
5358 }
5359 
5360 /**
5361  * @tc.name: HandleOnCopy003
5362  * @tc.desc: test InsertValueByPaste
5363  * @tc.type: FUNC
5364  */
5365 HWTEST_F(RichEditorTestNg, HandleOnCopy003, TestSize.Level1)
5366 {
5367     /**
5368      * @tc.steps: step1. init callback
5369      */
5370     RichEditorModelNG richEditorModel;
5371     richEditorModel.Create();
5372     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5373     ASSERT_NE(host, nullptr);
5374     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5375     ASSERT_NE(richEditorPattern, nullptr);
5376     auto pipeline = MockPipelineContext::GetCurrent();
5377     auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
5378     richEditorPattern->clipboard_ = clipboard;
5379     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5380     ASSERT_NE(eventHub, nullptr);
5381     bool isEventCalled = false;
__anon814dfc0d2c02(NG::TextCommonEvent& event) 5382     auto onCopyWithEvent = [&isEventCalled](NG::TextCommonEvent& event) {
5383         isEventCalled = true;
5384         event.SetPreventDefault(true);
5385     };
5386     richEditorModel.SetOnCopy(std::move(onCopyWithEvent));
5387 
5388     /**
5389      * @tc.steps: step2. call the callback function
5390      * @tc.expected: when PreventDefault is true, UpdateType_ and isEventCalled is valid
5391      */
5392     richEditorPattern->copyOption_ = CopyOptions::InApp;
5393     richEditorPattern->caretPosition_ = 0;
5394     richEditorPattern->textSelector_.baseOffset = 0;
5395     richEditorPattern->textSelector_.destinationOffset = 1;
5396     richEditorPattern->caretUpdateType_ = CaretUpdateType::PRESSED;
5397     richEditorPattern->HandleOnCopy();
5398     EXPECT_EQ(richEditorPattern->caretUpdateType_, CaretUpdateType::PRESSED);
5399     EXPECT_EQ(isEventCalled, true);
5400 }
5401 
5402 /**
5403  * @tc.name: ChangeTextCallbackTest001
5404  * @tc.desc: test for callback onWillchange/onWillDid
5405  * @tc.type: FUNC
5406  */
5407 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest001, TestSize.Level1)
5408 {
5409     /**
5410      * @tc.steps: step1. init callback
5411      */
5412     RichEditorModelNG richEditorModel;
5413     richEditorModel.Create();
5414     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5415     ASSERT_NE(host, nullptr);
5416     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5417     ASSERT_NE(richEditorPattern, nullptr);
5418     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5419     ASSERT_NE(eventHub, nullptr);
5420     bool isWillCalled = false;
5421     int32_t originalCount = 0;
5422     int32_t replacedCount = 0;
__anon814dfc0d2d02(const RichEditorChangeValue& beforeResult) 5423     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5424         isWillCalled = true;
5425         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5426         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5427         return false;
5428     };
5429     richEditorModel.SetOnWillChange(std::move(onWillChange));
5430     bool isDidCalled = false;
5431     int32_t afterCount = 0;
__anon814dfc0d2e02(const RichEditorChangeValue& afterResult) 5432     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5433         isDidCalled = true;
5434         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5435     };
5436     richEditorModel.SetOnDidChange(std::move(onDidChange));
5437 
5438     /**
5439      * @tc.steps: step2. change text with InsertValue When callback return false
5440      * @tc.expected: return value is valid
5441      */
5442     richEditorPattern->InsertValue(INIT_VALUE_1, true);
5443     EXPECT_EQ(isWillCalled, true);
5444     EXPECT_EQ(isDidCalled, false);
5445     EXPECT_EQ(originalCount, 0);
5446     EXPECT_EQ(replacedCount, 1);
5447     EXPECT_EQ(afterCount, 0);
5448 }
5449 
5450 /**
5451  * @tc.name: ChangeTextCallbackTest002
5452  * @tc.desc: test for callback onWillchange/onWillDid
5453  * @tc.type: FUNC
5454  */
5455 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest002, TestSize.Level1)
5456 {
5457     /**
5458      * @tc.steps: step1. init callback
5459      */
5460     RichEditorModelNG richEditorModel;
5461     richEditorModel.Create();
5462     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5463     ASSERT_NE(host, nullptr);
5464     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5465     ASSERT_NE(richEditorPattern, nullptr);
5466     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5467     ASSERT_NE(eventHub, nullptr);
5468     bool isWillCalled = false;
5469     int32_t originalCount = 0;
5470     int32_t replacedCount = 0;
__anon814dfc0d2f02(const RichEditorChangeValue& beforeResult) 5471     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5472         isWillCalled = true;
5473         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5474         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5475         return true;
5476     };
5477     richEditorModel.SetOnWillChange(std::move(onWillChange));
5478     bool isDidCalled = false;
5479     int32_t afterCount = 0;
__anon814dfc0d3002(const RichEditorChangeValue& afterResult) 5480     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5481         isDidCalled = true;
5482         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5483     };
5484     richEditorModel.SetOnDidChange(std::move(onDidChange));
5485 
5486     /**
5487      * @tc.steps: step2. change text with AddTextSpan
5488      * @tc.expected: return value is valid
5489      */
5490     TextSpanOptions textOptions;
5491     textOptions.value = INIT_VALUE_1;
5492     richEditorPattern->AddTextSpan(textOptions);
5493     EXPECT_EQ(isWillCalled, true);
5494     EXPECT_EQ(isDidCalled, true);
5495     EXPECT_EQ(originalCount, 0);
5496     EXPECT_EQ(replacedCount, 1);
5497     EXPECT_EQ(afterCount, 1);
5498 
5499     /**
5500      * @tc.steps: step3. change text with AddTextSpan of TextStyle
5501      * @tc.expected: return value is valid
5502      */
5503     isWillCalled = false;
5504     isDidCalled = false;
5505     originalCount = 0;
5506     replacedCount = 0;
5507     afterCount = 0;
5508     TextStyle style;
5509     textOptions.offset = 1;
5510     textOptions.value = INIT_VALUE_2;
5511     textOptions.style = style;
5512     richEditorPattern->AddTextSpan(textOptions);
5513     EXPECT_EQ(isWillCalled, true);
5514     EXPECT_EQ(isDidCalled, true);
5515     EXPECT_EQ(originalCount, 0);
5516     EXPECT_EQ(replacedCount, 1);
5517     EXPECT_EQ(afterCount, 1);
5518 }
5519 
5520 /**
5521  * @tc.name: ChangeTextCallbackTest003
5522  * @tc.desc: test for callback onWillchange/onWillDid
5523  * @tc.type: FUNC
5524  */
5525 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest003, TestSize.Level1)
5526 {
5527     /**
5528      * @tc.steps: step1. init callback
5529      */
5530     RichEditorModelNG richEditorModel;
5531     richEditorModel.Create();
5532     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5533     ASSERT_NE(host, nullptr);
5534     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5535     ASSERT_NE(richEditorPattern, nullptr);
5536     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5537     ASSERT_NE(eventHub, nullptr);
5538     bool isWillCalled = false;
5539     int32_t originalCount = 0;
5540     int32_t replacedCount = 0;
__anon814dfc0d3102(const RichEditorChangeValue& beforeResult) 5541     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5542         isWillCalled = true;
5543         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5544         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5545         return true;
5546     };
5547     richEditorModel.SetOnWillChange(std::move(onWillChange));
5548     bool isDidCalled = false;
5549     int32_t afterCount = 0;
__anon814dfc0d3202(const RichEditorChangeValue& afterResult) 5550     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5551         isDidCalled = true;
5552         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5553     };
5554     richEditorModel.SetOnDidChange(std::move(onDidChange));
5555 
5556     /**
5557      * @tc.steps: step2. change text with AddTextSpan
5558      * @tc.expected: return value is valid
5559      */
5560     TextSpanOptions textOptions;
5561     textOptions.value = INIT_VALUE_1;
5562     richEditorPattern->AddTextSpan(textOptions);
5563     EXPECT_EQ(isWillCalled, true);
5564     EXPECT_EQ(isDidCalled, true);
5565     EXPECT_EQ(originalCount, 0);
5566     EXPECT_EQ(replacedCount, 1);
5567     EXPECT_EQ(afterCount, 1);
5568 
5569     /**
5570      * @tc.steps: step3. change text with DeleteSpans
5571      * @tc.expected: return value is valid
5572      */
5573     isWillCalled = false;
5574     isDidCalled = false;
5575     originalCount = 0;
5576     replacedCount = 0;
5577     afterCount = 0;
5578     RangeOptions delOptions;
5579     delOptions.start = 0;
5580     delOptions.end = 2;
5581     richEditorPattern->DeleteSpans(delOptions);
5582     EXPECT_EQ(isWillCalled, true);
5583     EXPECT_EQ(isDidCalled, true);
5584     EXPECT_EQ(originalCount, 1);
5585     EXPECT_EQ(replacedCount, 0);
5586     EXPECT_EQ(afterCount, 0);
5587 }
5588 
5589 /**
5590  * @tc.name: ChangeTextCallbackTest004
5591  * @tc.desc: test for callback onWillchange/onWillDid
5592  * @tc.type: FUNC
5593  */
5594 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest004, TestSize.Level1)
5595 {
5596     /**
5597      * @tc.steps: step1. init callback
5598      */
5599     RichEditorModelNG richEditorModel;
5600     richEditorModel.Create();
5601     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5602     ASSERT_NE(host, nullptr);
5603     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5604     ASSERT_NE(richEditorPattern, nullptr);
5605     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5606     ASSERT_NE(eventHub, nullptr);
5607     bool isWillCalled = false;
5608     int32_t originalCount = 0;
5609     int32_t replacedCount = 0;
__anon814dfc0d3302(const RichEditorChangeValue& beforeResult) 5610     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5611         isWillCalled = true;
5612         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5613         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5614         return true;
5615     };
5616     richEditorModel.SetOnWillChange(std::move(onWillChange));
5617     bool isDidCalled = false;
5618     int32_t afterCount = 0;
__anon814dfc0d3402(const RichEditorChangeValue& afterResult) 5619     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5620         isDidCalled = true;
5621         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5622     };
5623     richEditorModel.SetOnDidChange(std::move(onDidChange));
5624 
5625     /**
5626      * @tc.steps: step2. change text with InsertValue
5627      * @tc.expected: return value is valid
5628      */
5629     richEditorPattern->InsertValue(INIT_VALUE_1, true);
5630     EXPECT_EQ(isWillCalled, true);
5631     EXPECT_EQ(isDidCalled, true);
5632     EXPECT_EQ(originalCount, 0);
5633     EXPECT_EQ(replacedCount, 1);
5634     EXPECT_EQ(afterCount, 1);
5635 
5636     /**
5637      * @tc.steps: step3. change text with multiLine
5638      * @tc.expected: return value is valid
5639      */
5640     isWillCalled = false;
5641     isDidCalled = false;
5642     originalCount = 0;
5643     replacedCount = 0;
5644     afterCount = 0;
5645     richEditorPattern->InsertValue("test\nvalue", true);
5646     EXPECT_EQ(isWillCalled, true);
5647     EXPECT_EQ(isDidCalled, true);
5648     EXPECT_EQ(originalCount, 0);
5649     EXPECT_EQ(replacedCount, 2);
5650     EXPECT_EQ(afterCount, 2);
5651 }
5652 
5653 /**
5654  * @tc.name: ChangeTextCallbackTest005
5655  * @tc.desc: test for callback onWillchange/onWillDid
5656  * @tc.type: FUNC
5657  */
5658 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest005, TestSize.Level1)
5659 {
5660     /**
5661      * @tc.steps: step1. init callback
5662      */
5663     RichEditorModelNG richEditorModel;
5664     richEditorModel.Create();
5665     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5666     ASSERT_NE(host, nullptr);
5667     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5668     ASSERT_NE(richEditorPattern, nullptr);
5669     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5670     ASSERT_NE(eventHub, nullptr);
5671     bool isWillCalled = false;
5672     int32_t originalCount = 0;
5673     int32_t replacedCount = 0;
__anon814dfc0d3502(const RichEditorChangeValue& beforeResult) 5674     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5675         isWillCalled = true;
5676         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5677         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5678         return true;
5679     };
5680     richEditorModel.SetOnWillChange(std::move(onWillChange));
5681     bool isDidCalled = false;
5682     int32_t afterCount = 0;
__anon814dfc0d3602(const RichEditorChangeValue& afterResult) 5683     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5684         isDidCalled = true;
5685         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5686     };
5687     richEditorModel.SetOnDidChange(std::move(onDidChange));
5688 
5689     /**
5690      * @tc.steps: step2. change text with ResetAfterPaste
5691      * @tc.expected: return value is valid
5692      */
5693     richEditorPattern->pasteStr_ = INIT_VALUE_1;
5694     richEditorPattern->ResetAfterPaste();
5695     EXPECT_EQ(isWillCalled, true);
5696     EXPECT_EQ(isDidCalled, true);
5697     EXPECT_EQ(originalCount, 0);
5698     EXPECT_EQ(replacedCount, 1);
5699     EXPECT_EQ(afterCount, 1);
5700 }
5701 
5702 /**
5703  * @tc.name: ChangeTextCallbackTest006
5704  * @tc.desc: test for callback onWillchange/onWillDid
5705  * @tc.type: FUNC
5706  */
5707 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest006, TestSize.Level1)
5708 {
5709     /**
5710      * @tc.steps: step1. init callback
5711      */
5712     RichEditorModelNG richEditorModel;
5713     richEditorModel.Create();
5714     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5715     ASSERT_NE(host, nullptr);
5716     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5717     ASSERT_NE(richEditorPattern, nullptr);
5718     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5719     ASSERT_NE(eventHub, nullptr);
5720     bool isWillCalled = false;
5721     int32_t originalCount = 0;
5722     int32_t replacedCount = 0;
__anon814dfc0d3702(const RichEditorChangeValue& beforeResult) 5723     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5724         isWillCalled = true;
5725         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5726         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5727         return true;
5728     };
5729     richEditorModel.SetOnWillChange(std::move(onWillChange));
5730     bool isDidCalled = false;
5731     int32_t afterCount = 0;
__anon814dfc0d3802(const RichEditorChangeValue& afterResult) 5732     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5733         isDidCalled = true;
5734         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5735     };
5736     richEditorModel.SetOnDidChange(std::move(onDidChange));
5737 
5738     /**
5739      * @tc.steps: step2. change text with HandleOnDragDropTextOperation
5740      * @tc.expected: return value is valid
5741      */
5742     richEditorPattern->InsertValue(INIT_VALUE_1, true);
5743     isWillCalled = false;
5744     isDidCalled = false;
5745     originalCount = 0;
5746     replacedCount = 0;
5747     afterCount = 0;
5748     richEditorPattern->caretPosition_ = 4;
5749     richEditorPattern->textSelector_.baseOffset = 0;
5750     richEditorPattern->textSelector_.destinationOffset = 2;
5751     richEditorPattern->dragRange_.first = 0;
5752     richEditorPattern->dragRange_.second = 2;
5753     richEditorPattern->isDragSponsor_ = true;
5754     richEditorPattern->HandleOnDragDropTextOperation("he", true);
5755     EXPECT_EQ(isWillCalled, true);
5756     EXPECT_EQ(isDidCalled, true);
5757     EXPECT_EQ(originalCount, 1);
5758     EXPECT_EQ(replacedCount, 1);
5759     EXPECT_EQ(afterCount, 1);
5760 }
5761 
5762 /**
5763  * @tc.name: ChangeTextCallbackTest007
5764  * @tc.desc: test for callback onWillchange/onWillDid
5765  * @tc.type: FUNC
5766  */
5767 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest007, TestSize.Level1)
5768 {
5769     /**
5770      * @tc.steps: step1. init callback
5771      */
5772     RichEditorModelNG richEditorModel;
5773     richEditorModel.Create();
5774     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5775     ASSERT_NE(host, nullptr);
5776     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5777     ASSERT_NE(richEditorPattern, nullptr);
5778     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5779     ASSERT_NE(eventHub, nullptr);
5780     bool isWillCalled = false;
5781     int32_t originalCount = 0;
5782     int32_t replacedCount = 0;
__anon814dfc0d3902(const RichEditorChangeValue& beforeResult) 5783     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5784         isWillCalled = true;
5785         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5786         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5787         return true;
5788     };
5789     richEditorModel.SetOnWillChange(std::move(onWillChange));
5790     bool isDidCalled = false;
5791     int32_t afterCount = 0;
__anon814dfc0d3a02(const RichEditorChangeValue& afterResult) 5792     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5793         isDidCalled = true;
5794         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5795     };
5796     richEditorModel.SetOnDidChange(std::move(onDidChange));
5797 
5798     /**
5799      * @tc.steps: step2. change text with HandleOnUndoAction
5800      * @tc.expected: return value is valid
5801      */
5802     richEditorPattern->InsertValue(INIT_VALUE_1, true);
5803     isWillCalled = false;
5804     isDidCalled = false;
5805     richEditorPattern->HandleOnUndoAction();
5806     EXPECT_EQ(isWillCalled, true);
5807     EXPECT_EQ(isDidCalled, true);
5808 
5809     /**
5810      * @tc.steps: step3. change text with HandleOnRedoAction
5811      * @tc.expected: return value is valid
5812      */
5813     isWillCalled = false;
5814     isDidCalled = false;
5815     originalCount = 0;
5816     replacedCount = 0;
5817     afterCount = 0;
5818     richEditorPattern->HandleOnRedoAction();
5819     EXPECT_EQ(isWillCalled, true);
5820     EXPECT_EQ(isDidCalled, true);
5821     EXPECT_EQ(originalCount, 0);
5822     EXPECT_EQ(replacedCount, 1);
5823     EXPECT_EQ(afterCount, 1);
5824 }
5825 
5826 /**
5827  * @tc.name: ChangeTextCallbackTest008
5828  * @tc.desc: test for callback onWillchange/onWillDid
5829  * @tc.type: FUNC
5830  */
5831 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest008, TestSize.Level1)
5832 {
5833     /**
5834      * @tc.steps: step1. init callback
5835      */
5836     RichEditorModelNG richEditorModel;
5837     richEditorModel.Create();
5838     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5839     ASSERT_NE(host, nullptr);
5840     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5841     ASSERT_NE(richEditorPattern, nullptr);
5842     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
5843     ASSERT_NE(eventHub, nullptr);
5844     bool isWillCalled = false;
5845     int32_t originalCount = 0;
5846     int32_t replacedCount = 0;
__anon814dfc0d3b02(const RichEditorChangeValue& beforeResult) 5847     auto onWillChange = [&isWillCalled, &originalCount, &replacedCount](const RichEditorChangeValue& beforeResult) {
5848         isWillCalled = true;
5849         originalCount = beforeResult.GetRichEditorOriginalSpans().size();
5850         replacedCount = beforeResult.GetRichEditorReplacedSpans().size();
5851         return true;
5852     };
5853     richEditorModel.SetOnWillChange(std::move(onWillChange));
5854     bool isDidCalled = false;
5855     int32_t afterCount = 0;
__anon814dfc0d3c02(const RichEditorChangeValue& afterResult) 5856     auto onDidChange = [&isDidCalled, &afterCount](const RichEditorChangeValue& afterResult) {
5857         isDidCalled = true;
5858         afterCount = afterResult.GetRichEditorReplacedSpans().size();
5859     };
5860     richEditorModel.SetOnDidChange(std::move(onDidChange));
5861 
5862     /**
5863      * @tc.steps: step2. change text with AddTextSpan & DeleteSpans & HandleOnUndoAction
5864      * @tc.expected: return value is valid
5865      */
5866     TextSpanOptions textOptions;
5867     textOptions.value = INIT_VALUE_1;
5868     richEditorPattern->AddTextSpan(textOptions);
5869     RangeOptions delOptions;
5870     delOptions.start = 0;
5871     delOptions.end = 2;
5872     richEditorPattern->DeleteSpans(delOptions);
5873     richEditorPattern->HandleOnUndoAction();
5874 
5875     /**
5876      * @tc.steps: step4. change text with HandleOnRedoAction
5877      * @tc.expected: return value is valid
5878      */
5879     isWillCalled = false;
5880     isDidCalled = false;
5881     originalCount = 0;
5882     replacedCount = 0;
5883     afterCount = 0;
5884     richEditorPattern->HandleOnRedoAction();
5885     EXPECT_EQ(isWillCalled, true);
5886     EXPECT_EQ(isDidCalled, true);
5887     EXPECT_EQ(originalCount, 1);
5888     EXPECT_EQ(replacedCount, 0);
5889     EXPECT_EQ(afterCount, 0);
5890 }
5891 
5892 /**
5893  * @tc.name: ChangeTextCallbackTest009
5894  * @tc.desc: test for callback onWillchange/onDidChange, add text span
5895  * @tc.type: FUNC
5896  */
5897 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest009, TestSize.Level1)
5898 {
5899     RichEditorModelNG richEditorModel;
5900     richEditorModel.Create();
5901     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5902     ASSERT_NE(host, nullptr);
5903     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5904     ASSERT_NE(richEditorPattern, nullptr);
5905     InitContentChangeCallback(richEditorModel);
5906 
5907     richEditorPattern->AddTextSpan(TEXT_SPAN_OPTIONS_1);
5908     EXPECT_EQ(g_isOnWillChangeCalled, true);
5909     EXPECT_EQ(g_isOnDidChangeCalled, true);
5910 
5911     // check onWill rangeBefore
5912     EXPECT_EQ(onWillRangeBefore.start, 0);
5913     EXPECT_EQ(onWillRangeBefore.end, 0);
5914 
5915     // check onWill span info
5916     ASSERT_EQ(onWillReplacedSpans.size(), 1);
5917     ASSERT_EQ(onWillReplacedImageSpans.size(), 0);
5918     ASSERT_EQ(onWillReplacedSymbolSpans.size(), 0);
5919 
5920     // check onDid rangeBefore
5921     EXPECT_EQ(onDidRangeBefore, onWillRangeBefore);
5922 
5923     // check onDid rangeAfter
5924     EXPECT_EQ(onDidRangeAfter.start, 0);
5925     EXPECT_EQ(onDidRangeAfter.end, 6); // length of INIT_VALUE_1
5926     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
5927         ViewStackProcessor::GetInstance()->elementsStack_.pop();
5928     }
5929 }
5930 
5931 /**
5932  * @tc.name: ChangeTextCallbackTest010
5933  * @tc.desc: test for callback onWillchange/onDidChange, add text span then insert value
5934  * @tc.type: FUNC
5935  */
5936 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest010, TestSize.Level1)
5937 {
5938     RichEditorModelNG richEditorModel;
5939     richEditorModel.Create();
5940     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5941     ASSERT_NE(host, nullptr);
5942     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5943     ASSERT_NE(richEditorPattern, nullptr);
5944     InitContentChangeCallback(richEditorModel);
5945 
5946     richEditorPattern->AddTextSpan(TEXT_SPAN_OPTIONS_1); // content = hello1
5947     richEditorPattern->textSelector_.Update(1, 5); // select h[ello]1
5948     richEditorPattern->InsertValue(INIT_VALUE_1, true);
5949 
5950     // check onWill rangeBefore
5951     EXPECT_EQ(onWillRangeBefore.start, 1);
5952     EXPECT_EQ(onWillRangeBefore.end, 5);
5953 
5954     // check onWill span info
5955     ASSERT_EQ(onWillReplacedSpans.size(), 1);
5956     ASSERT_EQ(onWillReplacedImageSpans.size(), 0);
5957     ASSERT_EQ(onWillReplacedSymbolSpans.size(), 0);
5958 
5959     auto& spanResult = onWillReplacedSpans[0];
5960     EXPECT_EQ(spanResult.spanIndex_, 0);
5961     EXPECT_EQ(spanResult.value_, "hhello11");
5962     EXPECT_EQ(spanResult.fontSize_, TEXT_STYLE_1.fontSize_.ConvertToPx());
5963     EXPECT_EQ(spanResult.offsetInSpan_, 1);
5964     EXPECT_EQ(spanResult.eraseLength_, 6);
5965 
5966     // check onDid rangeBefore
5967     EXPECT_EQ(onDidRangeBefore, onWillRangeBefore);
5968 
5969     // check onDid rangeAfter
5970     EXPECT_EQ(onDidRangeAfter.start, 1);
5971     EXPECT_EQ(onDidRangeAfter.end, 7); // h[ello]1 -> h[hello1]1
5972     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
5973         ViewStackProcessor::GetInstance()->elementsStack_.pop();
5974     }
5975 }
5976 
5977 /**
5978  * @tc.name: ChangeTextCallbackTest011
5979  * @tc.desc: test for callback onWillchange/onDidChange, add multi text span then insert value
5980  * @tc.type: FUNC
5981  */
5982 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest011, TestSize.Level1)
5983 {
5984     RichEditorModelNG richEditorModel;
5985     richEditorModel.Create();
5986     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
5987     ASSERT_NE(host, nullptr);
5988     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
5989     ASSERT_NE(richEditorPattern, nullptr);
5990     InitContentChangeCallback(richEditorModel);
5991 
5992     richEditorPattern->AddTextSpan(TEXT_SPAN_OPTIONS_1);
5993     richEditorPattern->AddTextSpan(TEXT_SPAN_OPTIONS_1);
5994     richEditorPattern->AddTextSpan(TEXT_SPAN_OPTIONS_1);
5995     // content = hello1hello1hello1
5996 
5997     richEditorPattern->textSelector_.Update(1, 17); // select h[ello1hello1hello]1
5998     richEditorPattern->InsertValue(INIT_VALUE_1, true);
5999 
6000     // check onWill rangeBefore
6001     EXPECT_EQ(onWillRangeBefore.start, 1);
6002     EXPECT_EQ(onWillRangeBefore.end, 17);
6003 
6004     // check onWill span info
6005     ASSERT_EQ(onWillReplacedSpans.size(), 1);
6006     ASSERT_EQ(onWillReplacedImageSpans.size(), 0);
6007     ASSERT_EQ(onWillReplacedSymbolSpans.size(), 0);
6008 
6009     auto& spanResult = onWillReplacedSpans[0];
6010     EXPECT_EQ(spanResult.spanIndex_, 0);
6011     EXPECT_EQ(spanResult.value_, "hhello1");
6012     EXPECT_EQ(spanResult.fontSize_, TEXT_STYLE_1.fontSize_.ConvertToPx());
6013     EXPECT_EQ(spanResult.offsetInSpan_, 1);
6014     EXPECT_EQ(spanResult.eraseLength_, 6);
6015 
6016     // check onDid rangeBefore
6017     EXPECT_EQ(onDidRangeBefore, onWillRangeBefore);
6018 
6019     // check onDid rangeAfter
6020     EXPECT_EQ(onDidRangeAfter.start, 1);
6021     EXPECT_EQ(onDidRangeAfter.end, 7); // h[ello1hello1hello]1 -> h[hello1]1
6022     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
6023         ViewStackProcessor::GetInstance()->elementsStack_.pop();
6024     }
6025 }
6026 
6027 /**
6028  * @tc.name: ChangeTextCallbackTest012
6029  * @tc.desc: test for callback onWillchange/onDidChange, add image span
6030  * @tc.type: FUNC
6031  */
6032 HWTEST_F(RichEditorTestNg, ChangeTextCallbackTest012, TestSize.Level1)
6033 {
6034     RichEditorModelNG richEditorModel;
6035     richEditorModel.Create();
6036     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
6037     ASSERT_NE(host, nullptr);
6038     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
6039     ASSERT_NE(richEditorPattern, nullptr);
6040     InitContentChangeCallback(richEditorModel);
6041 
6042     richEditorPattern->AddImageSpan(IMAGE_SPAN_OPTIONS_1);
6043 
6044     // check onWill rangeBefore
6045     EXPECT_EQ(onWillRangeBefore.start, 0);
6046     EXPECT_EQ(onWillRangeBefore.end, 0);
6047 
6048     // check onWill span info
6049     ASSERT_EQ(onWillReplacedSpans.size(), 0);
6050     ASSERT_EQ(onWillReplacedImageSpans.size(), 1);
6051     ASSERT_EQ(onWillReplacedSymbolSpans.size(), 0);
6052 
6053     auto& spanResult = onWillReplacedImageSpans[0];
6054     EXPECT_EQ(spanResult.spanIndex_, 0);
6055     EXPECT_EQ(spanResult.offsetInSpan_, 0);
6056     EXPECT_EQ(spanResult.eraseLength_, 1);
6057     EXPECT_EQ(spanResult.width_, 200);
6058     EXPECT_EQ(spanResult.height_, 100);
6059     EXPECT_EQ(spanResult.verticalAlign_, VerticalAlign::CENTER);
6060     EXPECT_EQ(spanResult.objectFit_, ImageFit::COVER);
6061 
6062     // check onDid rangeBefore
6063     EXPECT_EQ(onDidRangeBefore, onWillRangeBefore);
6064 
6065     // check onDid rangeAfter
6066     EXPECT_EQ(onDidRangeAfter.start, 0);
6067     EXPECT_EQ(onDidRangeAfter.end, 1);
6068     while (!ViewStackProcessor::GetInstance()->elementsStack_.empty()) {
6069         ViewStackProcessor::GetInstance()->elementsStack_.pop();
6070     }
6071 }
6072 
6073 /**
6074  * @tc.name: SupportAvoidanceTest
6075  * @tc.desc: test whether the custom keyboard supports the collision avoidance function
6076  * @tc.type: FUNC
6077  */
6078 HWTEST_F(RichEditorTestNg, SupportAvoidanceTest, TestSize.Level1)
6079 {
6080     auto pipeline = PipelineContext::GetCurrentContext();
6081     auto overlayManager = pipeline->GetOverlayManager();
6082     ASSERT_NE(richEditorNode_, nullptr);
6083     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6084     auto supportAvoidance = true;
6085     richEditorPattern->SetCustomKeyboardOption(supportAvoidance);
6086     auto support = richEditorPattern->keyboardAvoidance_;
6087     overlayManager->SetCustomKeyboardOption(support);
6088     EXPECT_TRUE(richEditorPattern->keyboardAvoidance_);
6089     supportAvoidance = false;
6090     richEditorPattern->SetCustomKeyboardOption(supportAvoidance);
6091     overlayManager->SetCustomKeyboardOption(support);
6092     EXPECT_FALSE(richEditorPattern->keyboardAvoidance_);
6093 }
6094 
6095 /**
6096  * @tc.name: SetPreviewText001
6097  * @tc.desc: test setPreviewText and decoration available
6098  * @tc.type: FUNC
6099  */
6100 HWTEST_F(RichEditorTestNg, SetPreviewText001, TestSize.Level1)
6101 {
6102     ASSERT_NE(richEditorNode_, nullptr);
6103     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6104     ASSERT_NE(richEditorPattern, nullptr);
6105     /**
6106      * @tc.steps: step1. set previewText
6107      */
6108     PreviewRange previewRange;
6109     previewRange.start = -1;
6110     previewRange.end = -1;
6111     richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange);
6112     /**
6113      * @tc.steps: step2. test previewText content
6114      */
6115     auto previewTextRecord = richEditorPattern->previewTextRecord_;
6116     auto previewContent = previewTextRecord.previewContent;
6117     EXPECT_EQ(previewContent, PREVIEW_TEXT_VALUE1);
6118     EXPECT_EQ(previewTextRecord.startOffset, 0);
6119     auto length = static_cast<int32_t>(StringUtils::ToWstring(PREVIEW_TEXT_VALUE1).length());
6120     EXPECT_EQ(previewTextRecord.endOffset, previewTextRecord.startOffset + length);
6121     /**
6122      * @tc.steps: step3. set previewTextDecoration
6123      */
6124     RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
6125     EXPECT_FALSE(geometryNode == nullptr);
6126     RefPtr<RenderContext> renderContext = RenderContext::Create();
6127     auto paintProperty = richEditorPattern->CreatePaintProperty();
6128     auto paintWrapper = AceType::MakeRefPtr<PaintWrapper>(renderContext, geometryNode, paintProperty);
6129     auto paintMethod = AceType::DynamicCast<RichEditorPaintMethod>(richEditorPattern->CreateNodePaintMethod());
6130     paintMethod->SetPreviewTextDecoration(AceType::RawPtr(paintWrapper));
6131     auto overlayMod =
6132         AceType::DynamicCast<RichEditorOverlayModifier>(paintMethod->GetOverlayModifier(AceType::RawPtr(paintWrapper)));
6133     ASSERT_NE(overlayMod, nullptr);
6134     /**
6135      * @tc.steps: step4. test previewTextDecoration
6136      */
6137     Testing::MockCanvas rsCanvas;
6138     EXPECT_CALL(rsCanvas, AttachBrush(_)).WillRepeatedly(ReturnRef(rsCanvas));
6139     EXPECT_CALL(rsCanvas, DetachBrush()).WillRepeatedly(ReturnRef(rsCanvas));
6140     EXPECT_CALL(rsCanvas, AttachPen(_)).WillRepeatedly(ReturnRef(rsCanvas));
6141     EXPECT_CALL(rsCanvas, DetachPen()).WillRepeatedly(ReturnRef(rsCanvas));
6142     DrawingContext context { rsCanvas, CONTEXT_WIDTH_VALUE, CONTEXT_HEIGHT_VALUE };
6143     overlayMod->PaintPreviewTextDecoration(context);
6144     EXPECT_EQ(overlayMod->showPreviewTextDecoration_->Get(), true);
6145 }
6146 
6147 /**
6148  * @tc.name: SetPreviewText002
6149  * @tc.desc: test setPreviewText init, update, and delete available
6150  * @tc.type: FUNC
6151  */
6152 HWTEST_F(RichEditorTestNg, SetPreviewText002, TestSize.Level1)
6153 {
6154     ASSERT_NE(richEditorNode_, nullptr);
6155     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6156     ASSERT_NE(richEditorPattern, nullptr);
6157     /**
6158      * @tc.steps: step1. set previewText
6159      */
6160     PreviewRange previewRange;
6161     previewRange.start = -1;
6162     previewRange.end = -1;
6163     richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange);
6164     /**
6165      * @tc.steps: step2. update previewText
6166      */
6167     richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE2, previewRange);
6168     /**
6169      * @tc.steps: step3. test previewText content
6170      */
6171     auto& previewTextRecord = richEditorPattern->previewTextRecord_;
6172     auto previewContent = previewTextRecord.previewContent;
6173     EXPECT_EQ(previewContent, PREVIEW_TEXT_VALUE2);
6174     EXPECT_EQ(previewTextRecord.startOffset, 0);
6175     auto length = static_cast<int32_t>(StringUtils::ToWstring(PREVIEW_TEXT_VALUE2).length());
6176     EXPECT_EQ(previewTextRecord.endOffset, previewTextRecord.startOffset + length);
6177     /**
6178      * @tc.steps: step4. delete content  previewText
6179      */
6180     richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE3, previewRange);
6181     auto previewContent2 = previewTextRecord.previewContent;
6182     EXPECT_EQ(previewContent2, PREVIEW_TEXT_VALUE3);
6183     EXPECT_EQ(previewTextRecord.startOffset, 0);
6184     length = static_cast<int32_t>(StringUtils::ToWstring(PREVIEW_TEXT_VALUE3).length());
6185     EXPECT_EQ(richEditorPattern->previewTextRecord_.endOffset, previewTextRecord.startOffset + length);
6186 }
6187 
6188 /**
6189  * @tc.name: FinishTextPreview001
6190  * @tc.desc: test FinishTextPreview available
6191  * @tc.type: FUNC
6192  */
6193 HWTEST_F(RichEditorTestNg, FinishTextPreview001, TestSize.Level1)
6194 {
6195     ASSERT_NE(richEditorNode_, nullptr);
6196     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6197     ASSERT_NE(richEditorPattern, nullptr);
6198     /**
6199      * @tc.steps: step1. set previewText
6200      */
6201     PreviewRange previewRange;
6202     previewRange.start = -1;
6203     previewRange.end = -1;
6204     richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange);
6205     /**
6206      * @tc.steps: step2.  FinishTextPreview
6207      */
6208     richEditorPattern->FinishTextPreview();
6209     /**
6210      * @tc.steps: step3. test previewText content
6211      */
6212     auto previewTextRecord = richEditorPattern->previewTextRecord_;
6213     auto previewContent = previewTextRecord.previewContent;
6214     EXPECT_EQ(previewContent, "");
6215     EXPECT_EQ(previewTextRecord.startOffset, -1);
6216     EXPECT_EQ(previewTextRecord.endOffset, -1);
6217 }
6218 
6219 /**
6220  * @tc.name: FinishTextPreview002
6221  * @tc.desc: test FinishTextPreview by insertValue available
6222  * @tc.type: FUNC
6223  */
6224 HWTEST_F(RichEditorTestNg, FinishTextPreview002, TestSize.Level1)
6225 {
6226     ASSERT_NE(richEditorNode_, nullptr);
6227     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6228     ASSERT_NE(richEditorPattern, nullptr);
6229     /**
6230      * @tc.steps: step1. set previewText
6231      */
6232     PreviewRange previewRange;
6233     previewRange.start = -1;
6234     previewRange.end = -1;
6235     richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange);
6236     /**
6237      * @tc.steps: step2.  test insertValue when previewTextInputting
6238      */
6239     richEditorPattern->InsertValue(PREVIEW_TEXT_VALUE1, true);
6240     EXPECT_EQ(richEditorPattern->spans_.size(), 1);
6241     auto it = richEditorPattern->spans_.begin();
6242     EXPECT_EQ((*it)->content, PREVIEW_TEXT_VALUE1);
6243 }
6244 
6245 /**
6246  * @tc.name: SingleHandle001
6247  * @tc.desc: test show single handle with empty text
6248  * @tc.type: FUNC
6249  */
6250 HWTEST_F(RichEditorTestNg, SingleHandle001, TestSize.Level1)
6251 {
6252     ASSERT_NE(richEditorNode_, nullptr);
6253     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6254     ASSERT_NE(richEditorPattern, nullptr);
6255     richEditorPattern->caretPosition_ = -1;
6256     /**
6257      * @tc.steps: step1. first click does not show single handle
6258      */
6259     GestureEvent info;
6260     info.localLocation_ = Offset(0, 0);
6261     richEditorPattern->HandleClickEvent(info);
6262     EXPECT_FALSE(richEditorPattern->selectOverlay_->IsSingleHandle());
6263     /**
6264      * @tc.steps: step2. repeat click caret position show single handle
6265      */
6266     info.localLocation_ = Offset(0, 0);
6267     richEditorPattern->HandleClickEvent(info);
6268     EXPECT_TRUE(richEditorPattern->selectOverlay_->IsSingleHandle());
6269     /**
6270      * @tc.steps: step3. repeat click away from caret position does not show single handle
6271      */
6272     richEditorPattern->selectOverlay_->SetIsSingleHandle(false);
6273     info.localLocation_ = Offset(50, 50);
6274     EXPECT_FALSE(richEditorPattern->selectOverlay_->IsSingleHandle());
6275     /**
6276      * @tc.steps: step4. double click or long press show single handle
6277      */
6278     richEditorPattern->HandleDoubleClickOrLongPress(info);
6279     EXPECT_TRUE(richEditorPattern->selectOverlay_->IsSingleHandle());
6280 }
6281 
6282 /**
6283  * @tc.name: SingleHandle002
6284  * @tc.desc: test show single handle with text
6285  * @tc.type: FUNC
6286  */
6287 HWTEST_F(RichEditorTestNg, SingleHandle002, TestSize.Level1)
6288 {
6289     ASSERT_NE(richEditorNode_, nullptr);
6290     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6291     ASSERT_NE(richEditorPattern, nullptr);
6292     /**
6293      * @tc.steps: step1. add text and paragraph
6294      */
6295     AddSpan(INIT_VALUE_1);
6296     TestParagraphItem paragraphItem = { .start = 0, .end = 6,
6297         .indexOffsetMap = { { 0, Offset(0, 5) }, { 6, Offset(50, 0) } } };
6298     AddParagraph(paragraphItem);
6299     /**
6300      * @tc.steps: step2. first click does not show single handle
6301      */
6302     richEditorPattern->caretPosition_ = -1;
6303     GestureEvent info;
6304     info.localLocation_ = Offset(0, 5);
6305     richEditorPattern->HandleClickEvent(info);
6306     EXPECT_FALSE(richEditorPattern->selectOverlay_->IsSingleHandle());
6307     /**
6308      * @tc.steps: step3. repeat click caret position show single handle
6309      */
6310     richEditorPattern->HandleClickEvent(info);
6311     EXPECT_TRUE(richEditorPattern->selectOverlay_->IsSingleHandle());
6312     /**
6313      * @tc.steps: step4. repeat click away from caret position does not show single handle
6314      */
6315     richEditorPattern->selectOverlay_->SetIsSingleHandle(false);
6316     info.localLocation_ = Offset(50, 0);
6317     richEditorPattern->HandleClickEvent(info);
6318     EXPECT_FALSE(richEditorPattern->selectOverlay_->IsSingleHandle());
6319     /**
6320      * @tc.steps: step5. double click or long press the end of text show single handle
6321      */
6322     richEditorPattern->HandleDoubleClickOrLongPress(info);
6323     EXPECT_TRUE(richEditorPattern->selectOverlay_->IsSingleHandle());
6324     /**
6325      * @tc.steps: step6. move single handle
6326      */
6327     auto handleOffset = OffsetF(0, 5);
6328     richEditorPattern->selectOverlay_->UpdateSelectorOnHandleMove(handleOffset, false);
6329     EXPECT_EQ(richEditorPattern->caretPosition_, 0);
6330 }
6331 
6332 /**
6333  * @tc.name: SingleHandle003
6334  * @tc.desc: test move caret by touch event
6335  * @tc.type: FUNC
6336  */
6337 HWTEST_F(RichEditorTestNg, SingleHandle003, TestSize.Level1)
6338 {
6339     ASSERT_NE(richEditorNode_, nullptr);
6340     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6341     ASSERT_NE(richEditorPattern, nullptr);
6342     /**
6343      * @tc.steps: step1. add text and paragraph
6344      */
6345     AddSpan(INIT_VALUE_1);
6346     TestParagraphItem paragraphItem = { .start = 0, .end = 6,
6347         .indexOffsetMap = { { 0, Offset(0, 0) }, { 6, Offset(50, 0) } } };
6348     AddParagraph(paragraphItem);
6349     /**
6350      * @tc.steps: step2. request foucus and show caret
6351      */
6352     RequestFocus();
6353     richEditorPattern->caretPosition_ = 0;
6354     richEditorPattern->StartTwinkling();
6355     /**
6356      * @tc.steps: step3. touch down caret position
6357      */
6358     auto touchOffset = Offset(0, 0);
6359     richEditorPattern->HandleTouchDown(touchOffset);
6360     EXPECT_TRUE(richEditorPattern->isTouchCaret_);
6361     /**
6362      * @tc.steps: step4. move caret position by touch move
6363      */
6364     touchOffset = Offset(50, 0);
6365     richEditorPattern->HandleTouchMove(touchOffset);
6366     EXPECT_EQ(richEditorPattern->caretPosition_, 6);
6367 }
6368 
6369 /**
6370  * @tc.name: IsSelectAreaVisible001
6371  * @tc.desc: test selectArea inVisible
6372  * @tc.type: FUNC
6373  */
6374 HWTEST_F(RichEditorTestNg, IsSelectAreaVisible001, TestSize.Level1)
6375 {
6376     ASSERT_NE(richEditorNode_, nullptr);
6377     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6378     ASSERT_NE(richEditorPattern, nullptr);
6379     /**
6380      * @tc.steps: step1. add text and paragraph
6381      */
6382     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 0.0, 0.0, 200.0, 200.0 } } };
6383     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
6384     AddParagraph(paragraphItem);
6385     richEditorPattern->textSelector_.baseOffset = 0;
6386     richEditorPattern->textSelector_.destinationOffset = 6;
6387     richEditorPattern->contentRect_ = { 0.0, 0.0, 500.0, 500.0 };
6388     /**
6389      * @tc.steps: step2. test IsSelectAreaVisible
6390      */
6391     auto res = richEditorPattern->IsSelectAreaVisible();
6392     EXPECT_FALSE(res);
6393 }
6394 
6395 /**
6396  * @tc.name: IsSelectAreaVisible002
6397  * @tc.desc: test selectArea Visible
6398  * @tc.type: FUNC
6399  */
6400 HWTEST_F(RichEditorTestNg, IsSelectAreaVisible002, TestSize.Level1)
6401 {
6402     ASSERT_NE(richEditorNode_, nullptr);
6403     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6404     ASSERT_NE(richEditorPattern, nullptr);
6405     /**
6406      * @tc.steps: step1. add text and paragraph
6407      */
6408     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { -400.0, -400.0, 200.0, 200.0 } } };
6409     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
6410     AddParagraph(paragraphItem);
6411     richEditorPattern->textSelector_.baseOffset = 0;
6412     richEditorPattern->textSelector_.destinationOffset = 6;
6413     richEditorPattern->contentRect_ = { -500.0, -500.0, 500.0, 500.0 };
6414     /**
6415      * @tc.steps: step2. test IsSelectAreaVisible
6416      */
6417     auto res = richEditorPattern->IsSelectAreaVisible();
6418     EXPECT_TRUE(res);
6419 }
6420 
6421 /**
6422  * @tc.name: onDraw001
6423  * @tc.desc: Verify the onDraw Magnifier.
6424  * @tc.type: FUNC
6425  */
6426 HWTEST_F(RichEditorTestNg, onDraw001, TestSize.Level1)
6427 {
6428     Offset localOffset(0, 0);
6429     SymbolSpanOptions symbolSpanOptions;
6430     symbolSpanOptions.symbolId = SYMBOL_ID;
6431 
6432     //Verify the selected single line text magnifying glass
6433     OnDrawVerify(SelectSpanType::TYPESPAN, INIT_VALUE_1, symbolSpanOptions, localOffset, true);
6434 
6435     //Verify the selected multi line text magnifying glass
6436     OnDrawVerify(SelectSpanType::TYPESPAN, INIT_VALUE_3, symbolSpanOptions, localOffset, true);
6437 
6438     //Verify the selected image magnifying glass
6439     OnDrawVerify(SelectSpanType::TYPEIMAGE, INIT_VALUE_1, symbolSpanOptions, localOffset, true);
6440 
6441     //Verify the selected symbol magnifying glass
6442     OnDrawVerify(SelectSpanType::TYPESYMBOLSPAN, INIT_VALUE_1, symbolSpanOptions, localOffset, true);
6443 
6444     //Verify insertion status with a regular text magnifying glass
6445     OnDrawVerify(SelectSpanType::TYPESPAN, INIT_VALUE_1, symbolSpanOptions, localOffset);
6446 
6447     //Verify the insertion status of the image magnifying glass
6448     OnDrawVerify(SelectSpanType::TYPEIMAGE, INIT_VALUE_1, symbolSpanOptions, localOffset);
6449 
6450     //Verify the insertion state symbol magnifying glass
6451     OnDrawVerify(SelectSpanType::TYPESYMBOLSPAN, INIT_VALUE_1, symbolSpanOptions, localOffset);
6452 }
6453 
6454 /**
6455  * @tc.name: StyledString001
6456  * @tc.desc: Test the styledString with image.
6457  * @tc.type: FUNC
6458  */
6459 HWTEST_F(RichEditorTestNg, StyledString001, TestSize.Level1)
6460 {
6461     /**
6462      * @tc.steps: step1. create styledString with image
6463      */
6464     ImageSpanSize size { .width = 50.0_vp, .height = 50.0_vp };
6465     BorderRadiusProperty borderRadius;
6466     borderRadius.SetRadius(2.0_vp);
6467     MarginProperty margins;
6468     margins.SetEdges(CalcLength(10.0));
6469     PaddingProperty paddings;
6470     paddings.SetEdges(CalcLength(5.0));
6471     ImageSpanAttribute attr { .size = size,
6472         .paddingProp = paddings,
6473         .marginProp = margins,
6474         .borderRadius = borderRadius,
6475         .objectFit = ImageFit::COVER,
6476         .verticalAlign = VerticalAlign::BOTTOM };
6477     ImageSpanOptions imageOption { .image = "src/icon-1.png", .imageAttribute = attr };
6478     auto mutableStr = AceType::MakeRefPtr<MutableSpanString>(imageOption);
6479     /**
6480      * @tc.steps: step2. get richEditor pattern
6481      */
6482     ASSERT_NE(richEditorNode_, nullptr);
6483     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6484     ASSERT_NE(richEditorPattern, nullptr);
6485     /**
6486      * @tc.steps: step3. set styledString
6487      */
6488     richEditorPattern->SetStyledString(mutableStr);
6489     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 1);
6490     auto child = richEditorPattern->GetChildByIndex(0);
6491     auto imageNode = AceType::DynamicCast<ImageSpanNode>(child);
6492     ASSERT_NE(imageNode, nullptr);
6493     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
6494     ASSERT_NE(imageLayoutProperty, nullptr);
6495     EXPECT_EQ(imageLayoutProperty->calcLayoutConstraint_->selfIdealSize, size.GetSize());
6496     EXPECT_EQ(imageLayoutProperty->GetVerticalAlignValue(), VerticalAlign::BOTTOM);
6497     EXPECT_EQ(imageLayoutProperty->GetImageFitValue(), ImageFit::COVER);
6498     auto&& padding = imageLayoutProperty->GetPaddingProperty();
6499     ASSERT_NE(padding, nullptr);
6500     EXPECT_EQ(padding->ToString(), paddings.ToString());
6501     auto imageRenderCtx = imageNode->GetRenderContext();
6502     ASSERT_NE(imageRenderCtx, nullptr);
6503     EXPECT_EQ(imageRenderCtx->GetBorderRadius(), borderRadius);
6504 }
6505 
6506 /**
6507  * @tc.name: StyledString002
6508  * @tc.desc: Test the styledString with image and text.
6509  * @tc.type: FUNC
6510  */
6511 HWTEST_F(RichEditorTestNg, StyledString002, TestSize.Level1)
6512 {
6513     /**
6514      * @tc.steps: step1. create styledString with image and text
6515      */
6516     ImageSpanOptions imageOption;
6517     auto mutableStr = AceType::MakeRefPtr<MutableSpanString>(imageOption);
6518     mutableStr->InsertString(0, "text");
6519     /**
6520      * @tc.steps: step2. get richEditor pattern
6521      */
6522     ASSERT_NE(richEditorNode_, nullptr);
6523     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
6524     ASSERT_NE(richEditorPattern, nullptr);
6525     /**
6526      * @tc.steps: step3. set styledString
6527      */
6528     richEditorPattern->SetStyledString(mutableStr);
6529     EXPECT_EQ(richEditorNode_->GetChildren().size(), 1);
6530     EXPECT_EQ(richEditorPattern->spans_.size(), 2);
6531     /**
6532      * @tc.steps: step5. insert other image
6533      */
6534     auto imageSpan = AceType::MakeRefPtr<SpanString>(imageOption);
6535     mutableStr->AppendSpanString(imageSpan);
6536     richEditorPattern->SetStyledString(mutableStr);
6537     EXPECT_EQ(richEditorNode_->GetChildren().size(), 2);
6538     EXPECT_EQ(richEditorPattern->spans_.size(), 3);
6539 }
6540 } // namespace OHOS::Ace::NG
6541