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