• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "test/unittest/adapter/ohos/capability/convert_test_tools.h"
17 
18 #undef private
19 #undef protected
20 
21 using namespace testing;
22 using namespace testing::ext;
23 namespace OHOS::Ace::NG {
24 
25 namespace {
26     std::string testStr[] = { "hello", "world", "this", "find", "gank", "pink", "that", "when", "how", "cpp" };
27     Font testFont1 { OHOS::Ace::FontWeight::BOLD, Dimension(29.0, DimensionUnit::PX), OHOS::Ace::FontStyle::ITALIC,
28         std::vector<std::string>(testStr, testStr + 10), OHOS::Ace::Color::BLUE };
29     Font testFont2 { OHOS::Ace::FontWeight::LIGHTER, Dimension(19.0, DimensionUnit::PX), OHOS::Ace::FontStyle::ITALIC,
30         std::vector<std::string>(testStr, testStr + 10), OHOS::Ace::Color::GRAY };
31     Font testEmptyFont {};
32 }
33 
34 /**
35  * @tc.name: SpanStringConvert000
36  * @tc.desc: This test case checks the conversion of a SpanString containing a mixture of different
37  *           spans including font, letter spacing, baseline offset, text decoration, text shadow,
38  *           and paragraph styles. It ensures that all styles are applied correctly and the conversion
39  *           between HTML and SpanString is accurate.
40  * @tc.level: 1
41  */
42 HWTEST_F(HtmlConvertTestNg, SpanStringConvert000, TestSize.Level1)
43 {
44     /**
45      * @tc.steps1: Initialize a mutable SpanString with an image option and create a SpanString with
46      *             mixed styles (font, letter spacing, baseline offset, text decoration, etc.).
47      * @tc.expected: The SpanString should properly handle different types of spans and apply them correctly.
48      */
49     auto imageOption = GetImageOption("src/icon-1.png");
50     auto mutableStr = AceType::MakeRefPtr<MutableSpanString>(imageOption);
51     auto spanString3 = AceType::MakeRefPtr<SpanString>(u"012345678\n9");
52 
53     // Add font spans with different font styles
54     spanString3->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont1, 0, 3));
55     spanString3->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont2, 3, 5));
56     spanString3->AddSpan(AceType::MakeRefPtr<FontSpan>(testEmptyFont, 5, 8));
57 
58     // Add baseline offset span
59     spanString3->AddSpan(AceType::MakeRefPtr<BaselineOffsetSpan>(Dimension(4), 0, 2));
60 
61     // Add letter spacing span
62     spanString3->AddSpan(AceType::MakeRefPtr<LetterSpacingSpan>(Dimension(5), 5, 8));
63 
64     // Add text decoration (line through) span
65     // change Test by search MakeRefPtr<DecorationSpan>
66     spanString3->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
67         std::vector<TextDecoration>({TextDecoration::LINE_THROUGH}), Color::BLUE,
68         TextDecorationStyle::WAVY, std::optional<TextDecorationOptions>(), 0, 1));
69 
70     // Add paragraph style span
71     auto spanParagraphStyle = GetDefaultParagraphStyle();
72     auto paraSpan = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 2, 5);
73     spanString3->AddSpan(paraSpan);
74 
75     // Add text shadow spans
76     Shadow textShadow;
77     textShadow.SetBlurRadius(0.0);
78     textShadow.SetColor(Color::BLUE);
79     textShadow.SetOffsetX(5.0);
80     textShadow.SetOffsetY(5.0);
81 
82     Shadow textShadow1;
83     textShadow1.SetBlurRadius(1.0);
84     textShadow1.SetColor(Color::BLUE);
85     textShadow1.SetOffsetX(10.0);
86     textShadow1.SetOffsetY(10.0);
87 
88     vector<Shadow> textShadows { textShadow, textShadow1 };
89     spanString3->AddSpan(AceType::MakeRefPtr<TextShadowSpan>(textShadows, 3, 6));
90 
91     // Insert the span string into the mutable string
92     mutableStr->InsertSpanString(1, spanString3);
93 
94     /**
95      * @tc.steps2: Create another SpanString with Chinese text, add font spans, letter spacing,
96      *             and insert it into the mutable string.
97      * @tc.expected: The second span string should be properly inserted and apply the added styles correctly.
98      */
99     auto spanString2 = AceType::MakeRefPtr<SpanString>(u"测试一下中文,\n看看是什么情况");
100     spanString2->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont1, 0, 5));
101     spanString2->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont2, 6, 10));
102     spanString2->AddSpan(AceType::MakeRefPtr<LetterSpacingSpan>(Dimension(10), 12, 14));
103 
104     // Insert this new SpanString into the mutable string
105     mutableStr->InsertSpanString(5, spanString2);
106 
107     /**
108      * @tc.steps3: Convert the mutable SpanString to HTML using the SpanToHtml converter.
109      * @tc.expected: The HTML conversion should preserve all the added spans and their properties.
110      */
111     SpanToHtml convert;
112     auto out = convert.ToHtml(*mutableStr);
113 
114     /**
115      * @tc.steps4: Convert the resulting HTML back to a SpanString and validate the number of span items.
116      * @tc.expected: The number of span items should match the total number of spans added.
117      */
118     HtmlToSpan toSpan;
119     auto dstSpan = toSpan.ToSpanString(out);
120     EXPECT_NE(dstSpan, nullptr);
121     auto items = dstSpan->GetSpanItems();
122     EXPECT_EQ(items.size(), 17);
123 }
124 
125 /**
126  * @tc.name: SpanStringConvert001
127  * @tc.desc: This test case verifies the conversion of a `SpanString` object to HTML and
128  *           back from HTML to `SpanString`.
129  *           It ensures that the content and structure are preserved during the entire conversion process.
130  * @tc.level: 1
131  */
132 HWTEST_F(HtmlConvertTestNg, SpanStringConvert001, TestSize.Level1)
133 {
134     /**
135      * @tc.steps1: Initialize parameters and create a `SpanString` object, adding different font style spans.
136      *             Each span represents a substring with a specific style (e.g., font, size, etc.).
137      * @tc.expected: The `SpanString` object should be correctly initialized with the given content and spans.
138      */
139     auto spanString = AceType::MakeRefPtr<SpanString>(u"0123456789");
140 
141     // Adding FontSpans with different fonts to the spanString
142     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont1, 0, 3));
143     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont2, 3, 5));
144     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testEmptyFont, 5, 8));
145 
146     /**
147      * @tc.steps2: Call the `ToHtml` function to convert the `SpanString` object to an HTML string.
148      *             First, use `EncodeTlv` method to convert the content into a byte buffer.
149      * @tc.expected: `u8ToHtml` should be a non-empty string representing the successful HTML conversion.
150      */
151     std::vector<uint8_t> buffer;
152     spanString->EncodeTlv(buffer);
153 
154     SpanToHtml convert;
155     auto u8ToHtml = convert.ToHtml(buffer);
156     EXPECT_NE(u8ToHtml.empty(), true);
157 
158     // Directly convert `SpanString` to HTML string
159     auto out = convert.ToHtml(*spanString);
160     EXPECT_NE(out.empty(), true);
161     EXPECT_EQ(out, u8ToHtml);
162 
163     /**
164      * @tc.steps3: Call the `ToSpanString` function to convert the HTML string back to a `SpanString` object.
165      * @tc.expected: The `ToSpanString` function should successfully convert the HTML back to a `SpanString`.
166      */
167     HtmlToSpan toSpan;
168     auto dstSpan = toSpan.ToSpanString(out);  // Convert the HTML string back to a SpanString
169     EXPECT_NE(dstSpan, nullptr);  // Expect the returned SpanString to be non-null
170 
171     // Get the SpanItems from the converted `SpanString`
172     auto items = dstSpan->GetSpanItems();
173     EXPECT_EQ(items.size(), 4);  // Expect the number of SpanItems to be 4, as there were 4 FontSpans added
174 
175     /**
176      * @tc.steps4: Verify that the number of SpanItems in the original `SpanString` matches the converted `SpanString`.
177      * @tc.expected: The number of SpanItems in the original `SpanString` and the converted `SpanString` be the same.
178      */
179     EXPECT_EQ(items.size(), spanString->GetSpanItems().size());
180 }
181 
182 /**
183  * @tc.name: SpanStringConvert002
184  * @tc.desc: This test case checks the HTML conversion when special HTML tags like `<strong>`, `<del>`,
185  *           and inline styles are used. It verifies that these elements are correctly converted to
186  *           `SpanString` and back to HTML.
187  * @tc.level: 1
188  */
189 HWTEST_F(HtmlConvertTestNg, SpanStringConvert002, TestSize.Level1)
190 {
191     /**
192      * @tc.steps1: Initialize HTML string containing special tags and inline styles.
193      * @tc.expected: The HTML should be properly formatted and support special tags like `<strong>`, `<del>`, etc.
194      */
195     const std::string fontHtml =
196         "<html>\n"
197         "<body>\n"
198         "<p>\n"
199         "<strong>Important Text</strong>\n"
200         "<del>Deleted Text</del>\n"
201         "</p>\n"
202         "</body>\n"
203         "</html>\n";
204 
205     /**
206      * @tc.steps2: Convert the HTML string to `SpanString`.
207      * @tc.expected: The conversion should result in a valid `SpanString` with correct `SpanItems` for the tags.
208      */
209     HtmlToSpan toSpan;
210     auto dstSpan = toSpan.ToSpanString(fontHtml);
211     EXPECT_NE(dstSpan, nullptr);
212     auto items = dstSpan->GetSpanItems();
213     EXPECT_GT(items.size(), 0);
214 
215     /**
216      * @tc.steps3: Convert the `SpanString` back to HTML and verify the result matches the original HTML.
217      * @tc.expected:  Verify that the outHtml's size is not empty.
218      */
219     SpanToHtml convert;
220     auto outHtml = convert.ToHtml(*dstSpan);
221     EXPECT_GT(outHtml.size(), 0);
222 }
223 
224 /**
225  * @tc.name: SpanStringConvert003
226  * @tc.desc: This test case checks the conversion when complex inline styles are applied to text.
227  *           It ensures that the font styles, color, and size are properly handled during the conversion.
228  * @tc.level: 1
229  */
230 HWTEST_F(HtmlConvertTestNg, SpanStringConvert003, TestSize.Level1)
231 {
232     /**
233      * @tc.steps1: Initialize HTML string with complex inline styles (font size, color, and weight).
234      * @tc.expected: The HTML should contain the correct inline styles for each text element.
235      */
236     const std::string complexHtml =
237         "<html>\n"
238         "<body>\n"
239         "<p style=\"font-size:20px; color:red; font-weight:bold;\">\n"
240         "Styled Text\n"
241         "</p>\n"
242         "</body>\n"
243         "</html>\n";
244 
245     /**
246      * @tc.steps2: Convert the HTML string to `SpanString`.
247      * @tc.expected: The conversion should parse the inline styles correctly and convert them into `FontSpan` objects.
248      */
249     HtmlToSpan toSpan;
250     auto dstSpan = toSpan.ToSpanString(complexHtml);
251     EXPECT_NE(dstSpan, nullptr);
252 
253     // Verify that the SpanItems reflect the correct styles (e.g., size, color, and weight)
254     auto items = dstSpan->GetSpanItems();
255     EXPECT_GT(items.size(), 0);
256 
257     /**
258      * @tc.steps3: Convert the `SpanString` back to HTML and ensure the inline styles are retained.
259      * @tc.expected: Verify that the outHtml's size is not empty.
260      */
261     SpanToHtml convert;
262     auto outHtml = convert.ToHtml(*dstSpan);
263     EXPECT_GT(outHtml.size(), 0);
264 }
265 
266 /**
267  * @tc.name: SpanStringConvert004
268  * @tc.desc: This test case verifies the behavior when converting HTML with embedded spans and complex inline elements.
269  *           It ensures that nested HTML elements like `<span>` are handled correctly during the conversion process.
270  * @tc.level: 1
271  */
272 HWTEST_F(HtmlConvertTestNg, SpanStringConvert004, TestSize.Level1)
273 {
274     /**
275      * @tc.steps1: Initialize HTML string with nested `<span>` tags and inline styles.
276      * @tc.expected: The HTML should contain nested spans with different styles.
277      */
278     const std::string nestedHtml = "<html>\n"
279                                    "<body>\n"
280                                    "<p>\n"
281                                    "<span style=\"color:blue;\">Blue Text</span>\n"
282                                    "<span style=\"color:red;\">Red Text</span>\n"
283                                    "</p>\n"
284                                    "</body>\n"
285                                    "</html>";
286     /**
287      * @tc.steps2: Convert the HTML string to `SpanString`.
288      * @tc.expected: The conversion should properly handle nested spans and inline styles.
289      */
290     HtmlToSpan toSpan;
291     auto dstSpan = toSpan.ToSpanString(nestedHtml);
292     EXPECT_NE(dstSpan, nullptr);
293 
294     // Verify that the SpanItems reflect the correct styles for each span
295     auto items = dstSpan->GetSpanItems();
296     EXPECT_GT(items.size(), 0);
297 
298     /**
299      * @tc.steps3: Convert the `SpanString` back to HTML and ensure that nested spans are correctly retained.
300      * @tc.expected: Verify that the outHtml's size is not empty.
301      */
302     SpanToHtml convert;
303     auto outHtml = convert.ToHtml(*dstSpan);
304     EXPECT_GT(outHtml.size(), 0);
305 }
306 
307 /**
308  * @tc.name: SpanStringConvert005
309  * @tc.desc: This test case checks the behavior when HTML contains elements with different text alignment properties.
310  *           It verifies that text alignment properties like `text-align` are properly converted and maintained.
311  * @tc.level: 1
312  */
313 HWTEST_F(HtmlConvertTestNg, SpanStringConvert005, TestSize.Level1)
314 {
315     /**
316      * @tc.steps1: Initialize HTML string with different text alignments (center, left, right).
317      * @tc.expected: The HTML should contain proper alignment properties for each element.
318      */
319     const std::string alignmentHtml = "<html>\n"
320                                       "<body>\n"
321                                       "<p style=\"text-align:center;\">Centered Text</p>\n"
322                                       "<p style=\"text-align:left;\">Left Aligned Text</p>\n"
323                                       "<p style=\"text-align:right;\">Right Aligned Text</p>\n"
324                                       "</body>\n"
325                                       "</html>";
326     /**
327      * @tc.steps2: Convert the HTML string to `SpanString`.
328      * @tc.expected: The conversion should properly handle text alignment properties for each text block.
329      */
330     HtmlToSpan toSpan;
331     auto dstSpan = toSpan.ToSpanString(alignmentHtml);
332     EXPECT_NE(dstSpan, nullptr);
333 
334     // Verify that the SpanItems reflect the correct alignment for each paragraph
335     auto items = dstSpan->GetSpanItems();
336     EXPECT_GT(items.size(), 0);
337 
338     /**
339      * @tc.steps3: Convert the `SpanString` back to HTML and ensure that text alignment properties are preserved.
340      * @tc.expected: Verify that the outHtml's size is not empty.
341      */
342     SpanToHtml convert;
343     auto outHtml = convert.ToHtml(*dstSpan);
344     EXPECT_GT(outHtml.size(), 0);
345 }
346 
347 /**
348  * @tc.name: SpanStringConvert006
349  * @tc.desc: This test case checks the conversion of a SpanString with multiple font spans and the
350  *           encoding/decoding of the span string into HTML and back. It verifies that the correct number
351  *           of span items is maintained and that the conversion preserves the span data.
352  * @tc.level: 1
353  */
354 HWTEST_F(HtmlConvertTestNg, SpanStringConvert006, TestSize.Level1)
355 {
356     /**
357      * @tc.steps1: Initialize a SpanString with a series of font spans (testFont1, testFont2, and testEmptyFont),
358      *             each covering different ranges of the string "0123456789".
359      * @tc.expected: Each span should correctly apply its respective font style to the
360      *               corresponding range in the string.
361      */
362     auto spanString = AceType::MakeRefPtr<SpanString>(u"0123456789");
363     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont1, 0, 3));
364     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont2, 3, 5));
365     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testEmptyFont, 5, 8));
366 
367     /**
368      * @tc.steps2: Encode the SpanString into a TLV (Type-Length-Value) format and convert it to HTML.
369      *             Check that the resulting HTML is not empty and is properly generated.
370      * @tc.expected: The conversion to HTML should produce a valid output, and the generated HTML should
371      *               match the encoded TLV version.
372      */
373     std::vector<uint8_t> buffer;
374     spanString->EncodeTlv(buffer);
375     SpanToHtml convert;
376     auto u8ToHtml = convert.ToHtml(buffer);
377     EXPECT_NE(u8ToHtml.empty(), true);
378 
379     auto out = convert.ToHtml(*spanString);
380     EXPECT_NE(out.empty(), true);
381     EXPECT_EQ(out, u8ToHtml);
382 
383     /**
384      * @tc.steps3: Convert the HTML back to a SpanString and validate that the number of span items is correct.
385      * @tc.expected: The number of span items in the resulting SpanString should match the original SpanString.
386      */
387     HtmlToSpan toSpan;
388     auto dstSpan = toSpan.ToSpanString(out);
389     EXPECT_NE(dstSpan, nullptr);
390     auto items = dstSpan->GetSpanItems();
391     EXPECT_EQ(items.size(), 4);
392 
393     /**
394      * @tc.steps4: Verify that the number of span items in the resulting SpanString matches the original.
395      * @tc.expected: The number of span items in the original SpanString should be the same as in
396      *               the converted SpanString.
397      */
398     EXPECT_EQ(items.size(), spanString->GetSpanItems().size());
399 }
400 
401 /**
402  * @tc.name: SpanStringConvert007
403  * @tc.desc: This test case checks the conversion of a MutableSpanString containing an image span and text.
404  *           It tests the handling of image spans during encoding and decoding to ensure proper HTML conversion.
405  * @tc.level: 1
406  */
407 HWTEST_F(HtmlConvertTestNg, SpanStringConvert007, TestSize.Level1)
408 {
409     /**
410      * @tc.steps1: Create a MutableSpanString with an image span and a text span, and encode the
411      *             MutableSpanString to a buffer.
412      * @tc.expected: The image span should be correctly encoded, and the HTML conversion hould match
413      *               the expected result.
414      */
415     auto imageOption = GetImageOption("src/icon-1.png");
416     auto imageSpan = AceType::MakeRefPtr<MutableSpanString>(imageOption);
417     auto mutableStr2 = AceType::MakeRefPtr<MutableSpanString>(u"123456");
418     imageSpan->AppendSpanString(mutableStr2);
419 
420     std::vector<uint8_t> buffer;
421     imageSpan->EncodeTlv(buffer);
422 
423     SpanToHtml convert;
424     auto u8ToHtml = convert.ToHtml(buffer);
425     EXPECT_NE(u8ToHtml.empty(), true);
426 
427     auto out = convert.ToHtml(*imageSpan);
428     EXPECT_NE(out.empty(), true);
429     EXPECT_EQ(out, u8ToHtml);
430 
431     HtmlToSpan toSpan;
432     auto dstSpan = toSpan.ToSpanString(out);
433     EXPECT_NE(dstSpan, nullptr);
434 
435     auto dstHtml = convert.ToHtml(*dstSpan);
436     EXPECT_EQ(out, dstHtml);
437 
438     // image is invalid,to html discart image the first char is not black space
439     auto spans = dstSpan->GetSpans(0, 6);
440     EXPECT_EQ(spans.size(), 2);
441 }
442 
443 /**
444  * @tc.name: SpanStringConvert008
445  * @tc.desc: This test case checks the conversion of a simple SpanString with basic text color and font size.
446  *           It ensures that the span string is correctly converted to HTML with the specified styles.
447  * @tc.level: 1
448  */
449 HWTEST_F(HtmlConvertTestNg, SpanStringConvert008, TestSize.Level1)
450 {
451     /**
452      * @tc.steps1: Create a SpanString with the text "简单的文本" and apply basic paragraph styles
453      *             including text alignment (left), text indent (0), word break (break_word),
454      *             and text overflow (clip).
455      * @tc.expected: The generated HTML should include basic font color and size styles.
456      */
457     auto spanString = AceType::MakeRefPtr<SpanString>(u"this is a normal text Hello WORLD");
458     SpanParagraphStyle spanParagraphStyle;
459     spanParagraphStyle.align = TextAlign::LEFT;
460     spanParagraphStyle.textIndent = Dimension(0.0_vp);
461     spanParagraphStyle.wordBreak = WordBreak::BREAK_WORD;
462     spanParagraphStyle.textOverflow = TextOverflow::CLIP;
463     spanParagraphStyle.leadingMargin = LeadingMargin();
464     spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(10.0_vp), Dimension(12.0));
465     auto paragraphStyle = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 0, 2);
466     spanString->AddSpan(paragraphStyle);
467 
468     /**
469      * @tc.steps2: Convert the SpanString to HTML using the SpanToHtml converter.
470      * @tc.expected: The resulting HTML should match the specified span and paragraph styles.
471      */
472     SpanToHtml convert;
473     auto out = convert.ToHtml(*spanString);
474     std::string result =
475         "<div ><p style=\"word-break: break_word;text-overflow: clip;\"><span style=\"font-size: 16.00px;"
476         "font-style: normal;font-weight: normal;color: #000000FF;font-family: HarmonyOS Sans;"
477         "stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: normal;\">th</span><span "
478         "style=\"font-size: 16.00px;font-style: normal;font-weight: normal;color: #000000FF;font-family: "
479         "HarmonyOS Sans;stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: normal;\">"
480         "is is a normal text Hello WORLD</span></p></div>";
481     EXPECT_EQ(out, result);
482 }
483 
484 /**
485  * @tc.name: SpanStringConvert009
486  * @tc.desc: This test case checks the conversion of a SpanString with text that is aligned to the center
487  *           and has an indentation applied. It ensures the HTML conversion reflects the correct text alignment
488  *           and indentation.
489  * @tc.level: 1
490  */
491 HWTEST_F(HtmlConvertTestNg, SpanStringConvert009, TestSize.Level1)
492 {
493     /**
494      * @tc.steps1: Create a SpanString with the text "居中的文本" and apply paragraph styles such as
495      *             center alignment, text indentation (20px), word break (break_word),
496      *             and text overflow (clip).
497      * @tc.expected: The generated HTML should reflect the correct text alignment (center) and indentation (20px).
498      */
499     auto spanString = AceType::MakeRefPtr<SpanString>(u"this text with CENTER BREAK_ALL textIndent property");
500     SpanParagraphStyle spanParagraphStyle;
501     spanParagraphStyle.align = TextAlign::CENTER;
502     spanParagraphStyle.textIndent = Dimension(20.0_vp);
503     spanParagraphStyle.wordBreak = WordBreak::BREAK_ALL;
504     spanParagraphStyle.textOverflow = TextOverflow::CLIP;
505     spanParagraphStyle.leadingMargin = LeadingMargin();
506     spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(12.0_vp), Dimension(14.0));
507     auto paragraphStyle = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 0, 5);
508     spanString->AddSpan(paragraphStyle);
509 
510     /**
511      * @tc.steps2: Convert the SpanString to HTML using the SpanToHtml converter.
512      * @tc.expected: The resulting HTML should match the specified paragraph and span styles.
513      */
514     SpanToHtml convert;
515     auto out = convert.ToHtml(*spanString);
516     std::string result =
517         "<div ><p style=\"text-align: center;text-indent: 20.00px;word-break: break_all;text-overflow: clip;\">"
518         "<span style=\"font-size: 16.00px;font-style: normal;font-weight: normal;color: #000000FF;"
519         "font-family: HarmonyOS Sans;stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: normal;\">"
520         "this </span><span style=\"font-size: 16.00px;font-style: normal;font-weight: normal;color: #000000FF;"
521         "font-family: HarmonyOS Sans;stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: normal;\">"
522         "text with CENTER BREAK_ALL textIndent property</span></p></div>";
523     EXPECT_EQ(out, result);
524 }
525 
526 /**
527  * @tc.name: SpanStringConvert010
528  * @tc.desc: This test case checks the conversion of a SpanString with mixed font sizes in the text,
529  *           verifying that the HTML conversion applies the correct font sizes to different spans within the same text.
530  * @tc.level: 1
531  */
532 HWTEST_F(HtmlConvertTestNg, SpanStringConvert010, TestSize.Level1)
533 {
534     /**
535      * @tc.steps1: Create a SpanString with the text "大<span style=\"font-size: 50px;\">小</span>的文本"
536      *             and apply appropriate font styles for each span element.
537      * @tc.expected: The HTML should reflect the correct font sizes for each part of the text.
538      */
539     auto spanString = AceType::MakeRefPtr<SpanString>(u"big 中文混排情况 text");
540     SpanParagraphStyle spanParagraphStyle;
541     spanParagraphStyle.align = TextAlign::LEFT;
542     spanParagraphStyle.textIndent = Dimension(0.0_vp);
543     spanParagraphStyle.wordBreak = WordBreak::BREAK_WORD;
544     spanParagraphStyle.textOverflow = TextOverflow::CLIP;
545     spanParagraphStyle.leadingMargin = LeadingMargin();
546     spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(10.0_vp), Dimension(12.0));
547     auto paragraphStyle = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 0, 7);
548     spanString->AddSpan(paragraphStyle);
549 
550     /**
551      * @tc.steps2: Convert the SpanString to HTML using the SpanToHtml converter.
552      * @tc.expected: The HTML should reflect the correct font sizes, with the word "小" being 50px,
553      *               while others remain 16px.
554      */
555     SpanToHtml convert;
556     auto out = convert.ToHtml(*spanString);
557     std::string result =
558         "<div ><p style=\"word-break: break_word;text-overflow: clip;\"><span style=\"font-size: 16.00px;"
559         "font-style: normal;font-weight: normal;color: #000000FF;font-family: HarmonyOS Sans;"
560         "stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: normal;\">big "
561         "\xE4\xB8\xAD\xE6\x96\x87\xE6\xB7\xB7</span><span style=\"font-size: 16.00px;font-style: normal;"
562         "font-weight: normal;color: #000000FF;font-family: HarmonyOS Sans;stroke-width: 0.00px;"
563         "stroke-color: #000000FF;font-superscript: normal;\">\xE6\x8E\x92\xE6\x83\x85\xE5\x86\xB5 text"
564         "</span></p></div>"; // xE4 etc is corresponding Chinese
565     EXPECT_EQ(out, result);
566 }
567 
568 /**
569  * @tc.name: SpanStringConvert011
570  * @tc.desc: This test case checks the conversion of a SpanString with mixed text styles including font size,
571  *           text shadow, and alignment. It ensures that the HTML conversion applies the correct styles
572  *           for both the paragraph and the individual spans.
573  * @tc.level: 1
574  */
575 HWTEST_F(HtmlConvertTestNg, SpanStringConvert011, TestSize.Level1)
576 {
577     /**
578      * @tc.steps1: Create a SpanString and apply complex paragraph styles and nested text shadow within the span.
579      * @tc.expected: The HTML should reflect the correct styles including text shadow for the nested span.
580      */
581     auto spanString = AceType::MakeRefPtr<SpanString>
582         (u"complext text span style= font size: 40px;text shadow: 0 0 3px red; shadow span ");
583     SpanParagraphStyle spanParagraphStyle;
584     spanParagraphStyle.align = TextAlign::START;
585     spanParagraphStyle.textIndent = Dimension(10.0_vp);
586     spanParagraphStyle.wordBreak = WordBreak::HYPHENATION;
587     spanParagraphStyle.textOverflow = TextOverflow::DEFAULT;
588     spanParagraphStyle.leadingMargin = LeadingMargin();
589     spanParagraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(20.0_vp), Dimension(30.0));
590     auto paragraphStyle = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 0, 7);
591     spanString->AddSpan(paragraphStyle);
592 
593     /**
594      * @tc.steps2: Convert the SpanString to HTML using the SpanToHtml converter.
595      * @tc.expected: The resulting HTML should include the correct text shadow and font size styles.
596      */
597     SpanToHtml convert;
598     auto out = convert.ToHtml(*spanString);
599     std::string result =
600         "<div ><p style=\"text-align: start;text-indent: 10.00px;\"><span style=\"font-size: 16.00px;"
601         "font-style: normal;font-weight: normal;color: #000000FF;font-family: HarmonyOS Sans;"
602         "stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: normal;\">complex</span>"
603         "<span style=\"font-size: 16.00px;font-style: normal;font-weight: normal;color: #000000FF;"
604         "font-family: HarmonyOS Sans;stroke-width: 0.00px;stroke-color: #000000FF;font-superscript: "
605         "normal;\">t text span style= font size: 40px;text shadow: 0 0 3px red; shadow span </span></p></div>";
606     EXPECT_EQ(out, result);
607 }
608 
609 /**
610  * @tc.name: SpanStringConvert012
611  * @tc.desc: This test case checks the conversion of a complex HTML string with various font styles,
612  *           including colors, font-family, font-size, and nested elements like strong and del tags.
613  *           It verifies that the HTML is correctly parsed and converted back to a SpanString.
614  * @tc.level: 1
615  */
616 HWTEST_F(HtmlConvertTestNg, SpanStringConvert012, TestSize.Level1)
617 {
618     /**
619      * @tc.steps1: Create a complex HTML string with various font styles and elements. Convert it to SpanString.
620      * @tc.expected: The SpanString should correctly represent the HTML content and its styles.
621      */
622     const std::string fontHtml = "<!DOCTYPE html>"
623                                  "<html>"
624                                  "<body>"
625                                  "<p>我是正常的</p>"
626                                  "<p style=\"COLOR:red;\">我是红色的</p>"
627                                  "<p style=\"font-family: 'Times New Roman', serif; font-size: 14px; font-weight: "
628                                  "normal; color: red; color: blue;\">我是蓝色的<strong style=\"color:blue; "
629                                  "font-size:100px;\">这段文字很重要!</strong><del>蓝色</del></p>"
630                                  "<p style=\"font-size:50px;\">我是50的</p>"
631                                  "</body>"
632                                  "</html>";
633     HtmlToSpan toSpan;
634     auto dstSpan = toSpan.ToSpanString(fontHtml);
635     EXPECT_NE(dstSpan, nullptr);
636 
637     SpanToHtml convert;
638     auto dstHtml = convert.ToHtml(*dstSpan);
639     HtmlToSpan toSpan1;
640     auto dstSpan1 = toSpan1.ToSpanString(dstHtml);
641     EXPECT_EQ(IsSpanItemSame(dstSpan->GetSpanItems(), dstSpan1->GetSpanItems()), true);
642     auto secondHtml = convert.ToHtml(*dstSpan1);
643     EXPECT_EQ(secondHtml, dstHtml);
644 }
645 
646 /**
647  * @tc.name: SpanStringConvert013
648  * @tc.desc: This test case checks the encoding and decoding of a simple SpanString with both English and Chinese.
649  *           It verifies that no information is lost during the encoding and decoding process.
650  * @tc.level: 1
651  */
652 HWTEST_F(HtmlConvertTestNg, SpanStringConvert013, TestSize.Level1)
653 {
654     /**
655      * @tc.steps1: Create a SpanString with mixed English and Chinese characters, and encode it to a buffer.
656      *             Convert the buffer to HTML and then convert it back to SpanString.
657      *             Finally, compare the original SpanString with the decoded SpanString.
658      * @tc.expected: The original SpanString and the decoded SpanString should be identical.
659      */
660     auto spanString = AceType::MakeRefPtr<SpanString>(u"01234中文56789");
661     std::vector<uint8_t> buff;
662     spanString->EncodeTlv(buff);
663     EXPECT_EQ(buff.size() > 0, true);
664     SpanToHtml toHtml;
665     auto htmlFromU8 = toHtml.ToHtml(buff);
666     auto htmlFromSpan = toHtml.ToHtml(*spanString); // 如果一致,说明编码和解码过程中没有丢失信息。
667     EXPECT_EQ(htmlFromU8, htmlFromSpan);
668 
669     HtmlToSpan toSpan;
670     auto spanFromHtml = toSpan.ToSpanString(htmlFromU8);
671     EXPECT_EQ(IsSpanItemSame(spanFromHtml->GetSpanItems(), spanString->GetSpanItems()), true);
672 
673     SpanToHtml toHtml1;
674     auto hmtlString = toHtml1.ToHtml(*spanFromHtml);
675     EXPECT_EQ(hmtlString, htmlFromSpan);
676 }
677 
678 /**
679  * @tc.name: SpanStringConvert014
680  * @tc.desc: This test case checks the conversion of a SpanString with multiple styles, including font spans,
681  *           letter spacing, and text decoration. It verifies that all styles are correctly applied and
682  *           preserved during conversion.
683  * @tc.level: 1
684  */
685 HWTEST_F(HtmlConvertTestNg, SpanStringConvert014, TestSize.Level1)
686 {
687     /**
688      * @tc.steps1: Create a SpanString with multiple spans, including font styles, letter spacing, and text decoration.
689      *             Convert it to HTML and then back to a SpanString.
690      *             Compare the span items to ensure no information is lost during the conversion process.
691      * @tc.expected: The converted SpanString should match the original SpanString with all styles applied correctly.
692      */
693     auto spanString = AceType::MakeRefPtr<SpanString>(u"0123456789");
694     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont1, 0, 3));
695     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont2, 3, 5));
696     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testEmptyFont, 5, 8));
697     spanString->AddSpan(AceType::MakeRefPtr<LetterSpacingSpan>(Dimension(5), 5, 8));
698     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
699         std::vector<TextDecoration>({TextDecoration::LINE_THROUGH}), Color::BLUE,
700         TextDecorationStyle::WAVY, std::optional<TextDecorationOptions>(), 0, 1));
701 
702     SpanToHtml convert;
703     auto out = convert.ToHtml(*spanString);
704     HtmlToSpan toSpan;
705     auto dstSpan = toSpan.ToSpanString(out);
706     EXPECT_EQ(IsSpanItemSame(dstSpan->GetSpanItems(), spanString->GetSpanItems()), true);
707 }
708 
709 /**
710  * @tc.name: HTMLLineThicknessScaleTest001
711  * @tc.desc: This test case checks the conversion of a SpanString containing a mixture of
712  *           spans. It ensures that all styles are applied correctly and the conversion
713  *           between HTML and SpanString is accurate.
714  * @tc.level: 1
715  */
716 HWTEST_F(HtmlConvertTestNg, HTMLLineThicknessScaleTest001, TestSize.Level1)
717 {
718     /**
719      * @tc.steps1: Initialize a mutable SpanString with an image option and create a SpanString with
720      *             mixed styles (font, letter spacing, baseline offset, text decoration, etc.).
721      * @tc.expected: The SpanString should properly handle different types of spans and apply them correctly.
722      */
723     auto imageOption = GetImageOption("src/appIcon-1.png");
724     auto mutableStr = AceType::MakeRefPtr<MutableSpanString>(imageOption);
725     auto spanString = AceType::MakeRefPtr<SpanString>(u"testNewDecoration\n123");
726 
727     // Add text decoration (line through) span
728     // change Test by search MakeRefPtr<DecorationSpan>
729     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
730         std::vector<TextDecoration>({TextDecoration::UNDERLINE}), Color::BLACK,
731         TextDecorationStyle::SOLID, 1.0f, std::optional<TextDecorationOptions>(), 0, 1));
732     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
733         std::vector<TextDecoration>({TextDecoration::UNDERLINE}), Color::BLACK,
734         TextDecorationStyle::WAVY, 5.0f, std::optional<TextDecorationOptions>(), 0, 1));
735     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
736         std::vector<TextDecoration>({TextDecoration::LINE_THROUGH}), Color::BLACK,
737         TextDecorationStyle::DASHED, -5.0f, std::optional<TextDecorationOptions>(), 0, 1));
738     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
739         std::vector<TextDecoration>({TextDecoration::LINE_THROUGH}), Color::BLACK,
740         TextDecorationStyle::DOTTED, 0, std::optional<TextDecorationOptions>(), 0, 1));
741 
742     // Add paragraph style span
743     auto spanParagraphStyle = GetDefaultParagraphStyle();
744     auto paragraphSpan = AceType::MakeRefPtr<ParagraphStyleSpan>(spanParagraphStyle, 4, 7);
745     spanString->AddSpan(paragraphSpan);
746 
747     // Insert the span string into the mutable string
748     mutableStr->InsertSpanString(2, spanString);
749 
750     /**
751      * @tc.steps3: Convert the mutable SpanString to HTML using the SpanToHtml converter.
752      * @tc.expected: The HTML conversion should preserve all the added spans and their properties.
753      */
754     SpanToHtml convert;
755     auto out = convert.ToHtml(*mutableStr);
756 
757     /**
758      * @tc.steps4: Convert the resulting HTML back to a SpanString and validate the number of span items.
759      * @tc.expected: The number of span items should match the total number of spans added.
760      */
761     HtmlToSpan toSpan;
762     auto dstSpan = toSpan.ToSpanString(out);
763     EXPECT_NE(dstSpan, nullptr);
764     auto items = dstSpan->GetSpanItems();
765     EXPECT_NE(items.size(), 0);
766 }
767 
768 /**
769  * @tc.name: HTMLLineThicknessScaleTest002
770  * @tc.desc: This test case checks the conversion of a SpanString with multiple styles,
771  *           It verifies that all styles are correctly applied and preserved during conversion.
772  * @tc.level: 1
773  */
774 HWTEST_F(HtmlConvertTestNg, HTMLLineThicknessScaleTest002, TestSize.Level1)
775 {
776     /**
777      * @tc.steps1: Create a SpanString with multiple spans
778      */
779     auto spanString = AceType::MakeRefPtr<SpanString>(u"testNewDecoration123");
780     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont1, 0, 6));
781     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testFont2, 6, 10));
782     spanString->AddSpan(AceType::MakeRefPtr<FontSpan>(testEmptyFont, 10, 12));
783     spanString->AddSpan(AceType::MakeRefPtr<LetterSpacingSpan>(Dimension(10), 5, 8));
784     /**
785      * @tc.steps2: Create a SpanString with multiple spans.
786      */
787     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
788         std::vector<TextDecoration>({TextDecoration::UNDERLINE}), Color::BLACK,
789         TextDecorationStyle::SOLID, 1.0f, std::optional<TextDecorationOptions>(), 0, 1));
790     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
791         std::vector<TextDecoration>({TextDecoration::LINE_THROUGH}), Color::BLACK,
792         TextDecorationStyle::SOLID, 5.0f, std::optional<TextDecorationOptions>(), 2, 6));
793     spanString->AddSpan(AceType::MakeRefPtr<DecorationSpan>(
794         std::vector<TextDecoration>({TextDecoration::OVERLINE}), Color::BLACK,
795         TextDecorationStyle::SOLID, -1.0f, std::optional<TextDecorationOptions>(), 7, 9));
796     /**
797      * @tc.steps3: Create a SpanString with multiple spans, including font styles, etc.
798      */
799     SpanToHtml convert;
800     auto out = convert.ToHtml(*spanString);
801     HtmlToSpan toSpan;
802     auto dstSpan = toSpan.ToSpanString(out);
803     EXPECT_EQ(IsSpanItemSame(dstSpan->GetSpanItems(), spanString->GetSpanItems()), true);
804 }
805 
806 } // namespace OHOS::Ace::NG