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