HashtagTests.swift (22050B)
1 // 2 // HashtagTests.swift 3 // damusTests 4 // 5 // Created by William Casarin on 2023-07-11. 6 // Modified by Jon Marrs on 2023-09-12. 7 // 8 9 import XCTest 10 @testable import damus 11 12 final class HashtagTests: XCTestCase { 13 14 // Basic hashtag tests 15 16 func testParseHashtag() { 17 let parsed = parse_note_content(content: .content("some hashtag #bitcoin derp",nil)).blocks 18 19 XCTAssertNotNil(parsed) 20 XCTAssertEqual(parsed.count, 3) 21 XCTAssertEqual(parsed[0].asText, "some hashtag ") 22 XCTAssertEqual(parsed[1].asHashtag, "bitcoin") 23 XCTAssertEqual(parsed[2].asText, " derp") 24 } 25 26 func testParseHashtagEnd() { 27 let parsed = parse_note_content(content: .content("some hashtag #bitcoin",nil)).blocks 28 29 XCTAssertNotNil(parsed) 30 XCTAssertEqual(parsed.count, 2) 31 XCTAssertEqual(parsed[0].asText, "some hashtag ") 32 XCTAssertEqual(parsed[1].asHashtag, "bitcoin") 33 } 34 35 //------------------------------------------------------------ 36 // Test ASCII 37 //------------------------------------------------------------ 38 39 // Test ASCII punctuation exceptions (punctuation that is allowed in hashtags) 40 41 // Underscores are allowed in hashtags 42 func testHashtagWithUnderscore() { 43 let parsed = parse_note_content(content: .content("the #under_score is allowed in hashtags",nil)).blocks 44 45 XCTAssertNotNil(parsed) 46 XCTAssertEqual(parsed.count, 3) 47 XCTAssertEqual(parsed[0].asText, "the ") 48 XCTAssertEqual(parsed[1].asHashtag, "under_score") 49 XCTAssertEqual(parsed[2].asText, " is allowed in hashtags") 50 } 51 52 // Test ASCII punctuation (not allowed in hashtags) 53 54 func testHashtagWithComma() { 55 let parsed = parse_note_content(content: .content("the #comma, is not allowed",nil)).blocks 56 57 XCTAssertNotNil(parsed) 58 XCTAssertEqual(parsed.count, 3) 59 XCTAssertEqual(parsed[0].asText, "the ") 60 XCTAssertEqual(parsed[1].asHashtag, "comma") 61 XCTAssertEqual(parsed[2].asText, ", is not allowed") 62 } 63 64 func testHashtagWithPeriod() { 65 let parsed = parse_note_content(content: .content("the #period. is not allowed",nil)).blocks 66 67 XCTAssertNotNil(parsed) 68 XCTAssertEqual(parsed.count, 3) 69 XCTAssertEqual(parsed[0].asText, "the ") 70 XCTAssertEqual(parsed[1].asHashtag, "period") 71 XCTAssertEqual(parsed[2].asText, ". is not allowed") 72 } 73 74 func testHashtagWithQuestionMark() { 75 let parsed = parse_note_content(content: .content("the #question?mark is not allowed",nil)).blocks 76 77 XCTAssertNotNil(parsed) 78 XCTAssertEqual(parsed.count, 3) 79 XCTAssertEqual(parsed[0].asText, "the ") 80 XCTAssertEqual(parsed[1].asHashtag, "question") 81 XCTAssertEqual(parsed[2].asText, "?mark is not allowed") 82 } 83 84 func testHashtagWithGraveAccent() { 85 let parsed = parse_note_content(content: .content("the #grave`accent is not allowed",nil)).blocks 86 87 XCTAssertNotNil(parsed) 88 XCTAssertEqual(parsed.count, 3) 89 XCTAssertEqual(parsed[0].asText, "the ") 90 XCTAssertEqual(parsed[1].asHashtag, "grave") 91 XCTAssertEqual(parsed[2].asText, "`accent is not allowed") 92 } 93 94 func testHashtagWithTilde() { 95 let parsed = parse_note_content(content: .content("the #tilde~ is not allowed",nil)).blocks 96 97 XCTAssertNotNil(parsed) 98 XCTAssertEqual(parsed.count, 3) 99 XCTAssertEqual(parsed[0].asText, "the ") 100 XCTAssertEqual(parsed[1].asHashtag, "tilde") 101 XCTAssertEqual(parsed[2].asText, "~ is not allowed") 102 } 103 104 func testHashtagWithExclamationPoint() { 105 let parsed = parse_note_content(content: .content("the #exclamation!point is not allowed",nil)).blocks 106 107 XCTAssertNotNil(parsed) 108 XCTAssertEqual(parsed.count, 3) 109 XCTAssertEqual(parsed[0].asText, "the ") 110 XCTAssertEqual(parsed[1].asHashtag, "exclamation") 111 XCTAssertEqual(parsed[2].asText, "!point is not allowed") 112 } 113 114 func testHashtagWithAtSign() { 115 let parsed = parse_note_content(content: .content("the #at@sign is not allowed",nil)).blocks 116 117 XCTAssertNotNil(parsed) 118 XCTAssertEqual(parsed.count, 3) 119 XCTAssertEqual(parsed[0].asText, "the ") 120 XCTAssertEqual(parsed[1].asHashtag, "at") 121 XCTAssertEqual(parsed[2].asText, "@sign is not allowed") 122 } 123 124 func testHashtagWithDollarSign() { 125 let parsed = parse_note_content(content: .content("the #dollar$sign is not allowed",nil)).blocks 126 127 XCTAssertNotNil(parsed) 128 XCTAssertEqual(parsed.count, 3) 129 XCTAssertEqual(parsed[0].asText, "the ") 130 XCTAssertEqual(parsed[1].asHashtag, "dollar") 131 XCTAssertEqual(parsed[2].asText, "$sign is not allowed") 132 } 133 134 func testHashtagWithPercentSign() { 135 let parsed = parse_note_content(content: .content("the #percent%sign is not allowed",nil)).blocks 136 137 XCTAssertNotNil(parsed) 138 XCTAssertEqual(parsed.count, 3) 139 XCTAssertEqual(parsed[0].asText, "the ") 140 XCTAssertEqual(parsed[1].asHashtag, "percent") 141 XCTAssertEqual(parsed[2].asText, "%sign is not allowed") 142 } 143 144 func testHashtagWithCaret() { 145 let parsed = parse_note_content(content: .content("the #caret^ is not allowed",nil)).blocks 146 147 XCTAssertNotNil(parsed) 148 XCTAssertEqual(parsed.count, 3) 149 XCTAssertEqual(parsed[0].asText, "the ") 150 XCTAssertEqual(parsed[1].asHashtag, "caret") 151 XCTAssertEqual(parsed[2].asText, "^ is not allowed") 152 } 153 154 func testHashtagWithAmpersand() { 155 let parsed = parse_note_content(content: .content("the #ampersand& is not allowed",nil)).blocks 156 157 XCTAssertNotNil(parsed) 158 XCTAssertEqual(parsed.count, 3) 159 XCTAssertEqual(parsed[0].asText, "the ") 160 XCTAssertEqual(parsed[1].asHashtag, "ampersand") 161 XCTAssertEqual(parsed[2].asText, "& is not allowed") 162 } 163 164 func testHashtagWithAsterisk() { 165 let parsed = parse_note_content(content: .content("the #asterisk* is not allowed",nil)).blocks 166 167 XCTAssertNotNil(parsed) 168 XCTAssertEqual(parsed.count, 3) 169 XCTAssertEqual(parsed[0].asText, "the ") 170 XCTAssertEqual(parsed[1].asHashtag, "asterisk") 171 XCTAssertEqual(parsed[2].asText, "* is not allowed") 172 } 173 174 func testHashtagWithLeftParenthesis() { 175 let parsed = parse_note_content(content: .content("the #left(parenthesis is not allowed",nil)).blocks 176 177 XCTAssertNotNil(parsed) 178 XCTAssertEqual(parsed.count, 3) 179 XCTAssertEqual(parsed[0].asText, "the ") 180 XCTAssertEqual(parsed[1].asHashtag, "left") 181 XCTAssertEqual(parsed[2].asText, "(parenthesis is not allowed") 182 } 183 184 func testHashtagWithRightParenthesis() { 185 let parsed = parse_note_content(content: .content("the #right)parenthesis is not allowed",nil)).blocks 186 187 XCTAssertNotNil(parsed) 188 XCTAssertEqual(parsed.count, 3) 189 XCTAssertEqual(parsed[0].asText, "the ") 190 XCTAssertEqual(parsed[1].asHashtag, "right") 191 XCTAssertEqual(parsed[2].asText, ")parenthesis is not allowed") 192 } 193 194 func testHashtagWithDash() { 195 let parsed = parse_note_content(content: .content("the #dash- is not allowed",nil)).blocks 196 197 XCTAssertNotNil(parsed) 198 XCTAssertEqual(parsed.count, 3) 199 XCTAssertEqual(parsed[0].asText, "the ") 200 XCTAssertEqual(parsed[1].asHashtag, "dash") 201 XCTAssertEqual(parsed[2].asText, "- is not allowed") 202 } 203 204 func testHashtagWithPlusSign() { 205 let parsed = parse_note_content(content: .content("the #plus+sign is not allowed",nil)).blocks 206 207 XCTAssertNotNil(parsed) 208 XCTAssertEqual(parsed.count, 3) 209 XCTAssertEqual(parsed[0].asText, "the ") 210 XCTAssertEqual(parsed[1].asHashtag, "plus") 211 XCTAssertEqual(parsed[2].asText, "+sign is not allowed") 212 } 213 214 func testHashtagWithEqualsSign() { 215 let parsed = parse_note_content(content: .content("the #equals=sign is not allowed",nil)).blocks 216 217 XCTAssertNotNil(parsed) 218 XCTAssertEqual(parsed.count, 3) 219 XCTAssertEqual(parsed[0].asText, "the ") 220 XCTAssertEqual(parsed[1].asHashtag, "equals") 221 XCTAssertEqual(parsed[2].asText, "=sign is not allowed") 222 } 223 224 func testHashtagWithLeftBracket() { 225 let parsed = parse_note_content(content: .content("the #left[bracket is not allowed",nil)).blocks 226 227 XCTAssertNotNil(parsed) 228 XCTAssertEqual(parsed.count, 3) 229 XCTAssertEqual(parsed[0].asText, "the ") 230 XCTAssertEqual(parsed[1].asHashtag, "left") 231 XCTAssertEqual(parsed[2].asText, "[bracket is not allowed") 232 } 233 234 func testHashtagWithRightBracket() { 235 let parsed = parse_note_content(content: .content("the #right]bracket is not allowed",nil)).blocks 236 237 XCTAssertNotNil(parsed) 238 XCTAssertEqual(parsed.count, 3) 239 XCTAssertEqual(parsed[0].asText, "the ") 240 XCTAssertEqual(parsed[1].asHashtag, "right") 241 XCTAssertEqual(parsed[2].asText, "]bracket is not allowed") 242 } 243 244 func testHashtagWithLeftBrace() { 245 let parsed = parse_note_content(content: .content("the #left{brace is not allowed",nil)).blocks 246 247 XCTAssertNotNil(parsed) 248 XCTAssertEqual(parsed.count, 3) 249 XCTAssertEqual(parsed[0].asText, "the ") 250 XCTAssertEqual(parsed[1].asHashtag, "left") 251 XCTAssertEqual(parsed[2].asText, "{brace is not allowed") 252 } 253 254 func testHashtagWithRightBrace() { 255 let parsed = parse_note_content(content: .content("the #right}brace is not allowed",nil)).blocks 256 257 XCTAssertNotNil(parsed) 258 XCTAssertEqual(parsed.count, 3) 259 XCTAssertEqual(parsed[0].asText, "the ") 260 XCTAssertEqual(parsed[1].asHashtag, "right") 261 XCTAssertEqual(parsed[2].asText, "}brace is not allowed") 262 } 263 264 func testHashtagWithBackslash() { 265 let parsed = parse_note_content(content: .content("the #back\\slash is not allowed",nil)).blocks 266 267 XCTAssertNotNil(parsed) 268 XCTAssertEqual(parsed.count, 3) 269 XCTAssertEqual(parsed[0].asText, "the ") 270 XCTAssertEqual(parsed[1].asHashtag, "back") 271 XCTAssertEqual(parsed[2].asText, "\\slash is not allowed") 272 } 273 274 func testHashtagWithVerticalLine() { 275 let parsed = parse_note_content(content: .content("the #vertical|line is not allowed",nil)).blocks 276 277 XCTAssertNotNil(parsed) 278 XCTAssertEqual(parsed.count, 3) 279 XCTAssertEqual(parsed[0].asText, "the ") 280 XCTAssertEqual(parsed[1].asHashtag, "vertical") 281 XCTAssertEqual(parsed[2].asText, "|line is not allowed") 282 } 283 284 func testHashtagWithSemicolon() { 285 let parsed = parse_note_content(content: .content("the #semicolon; is not allowed",nil)).blocks 286 287 XCTAssertNotNil(parsed) 288 XCTAssertEqual(parsed.count, 3) 289 XCTAssertEqual(parsed[0].asText, "the ") 290 XCTAssertEqual(parsed[1].asHashtag, "semicolon") 291 XCTAssertEqual(parsed[2].asText, "; is not allowed") 292 } 293 294 func testHashtagWithColon() { 295 let parsed = parse_note_content(content: .content("the #colon: is not allowed",nil)).blocks 296 297 XCTAssertNotNil(parsed) 298 XCTAssertEqual(parsed.count, 3) 299 XCTAssertEqual(parsed[0].asText, "the ") 300 XCTAssertEqual(parsed[1].asHashtag, "colon") 301 XCTAssertEqual(parsed[2].asText, ": is not allowed") 302 } 303 304 func testHashtagWithApostrophe() { 305 let parsed = parse_note_content(content: .content("the #apostrophe' is not allowed",nil)).blocks 306 307 XCTAssertNotNil(parsed) 308 XCTAssertEqual(parsed.count, 3) 309 XCTAssertEqual(parsed[0].asText, "the ") 310 XCTAssertEqual(parsed[1].asHashtag, "apostrophe") 311 XCTAssertEqual(parsed[2].asText, "' is not allowed") 312 } 313 314 func testHashtagWithQuotationMark() { 315 let parsed = parse_note_content(content: .content("the #quotation\"mark is not allowed",nil)).blocks 316 317 XCTAssertNotNil(parsed) 318 XCTAssertEqual(parsed.count, 3) 319 XCTAssertEqual(parsed[0].asText, "the ") 320 XCTAssertEqual(parsed[1].asHashtag, "quotation") 321 XCTAssertEqual(parsed[2].asText, "\"mark is not allowed") 322 } 323 324 func testHashtagWithLessThanSign() { 325 let parsed = parse_note_content(content: .content("the #lessthan<sign is not allowed",nil)).blocks 326 327 XCTAssertNotNil(parsed) 328 XCTAssertEqual(parsed.count, 3) 329 XCTAssertEqual(parsed[0].asText, "the ") 330 XCTAssertEqual(parsed[1].asHashtag, "lessthan") 331 XCTAssertEqual(parsed[2].asText, "<sign is not allowed") 332 } 333 334 func testHashtagWithGreaterThanSign() { 335 let parsed = parse_note_content(content: .content("the #greaterthan>sign is not allowed",nil)).blocks 336 337 XCTAssertNotNil(parsed) 338 XCTAssertEqual(parsed.count, 3) 339 XCTAssertEqual(parsed[0].asText, "the ") 340 XCTAssertEqual(parsed[1].asHashtag, "greaterthan") 341 XCTAssertEqual(parsed[2].asText, ">sign is not allowed") 342 } 343 344 //------------------------------------------------------------ 345 // Test Unicode (UTF-8) 346 //------------------------------------------------------------ 347 348 // Test UTF-8 Latin-1 Supplement Punctuation: U+00A1 to U+00BF (not allowed) 349 350 // Test pound sign (£) (U+00A3) 351 func testHashtagWithPoundSign() { 352 let parsed = parse_note_content(content: .content("the #pound£sign is not allowed",nil)).blocks 353 354 XCTAssertNotNil(parsed) 355 XCTAssertEqual(parsed.count, 3) 356 XCTAssertEqual(parsed[0].asText, "the ") 357 XCTAssertEqual(parsed[1].asHashtag, "pound") 358 XCTAssertEqual(parsed[2].asText, "£sign is not allowed") 359 } 360 361 // Test yen sign (¥) (U+00A5) 362 func testHashtagWithYenSign() { 363 let parsed = parse_note_content(content: .content("the #yen¥sign is not allowed",nil)).blocks 364 365 XCTAssertNotNil(parsed) 366 XCTAssertEqual(parsed.count, 3) 367 XCTAssertEqual(parsed[0].asText, "the ") 368 XCTAssertEqual(parsed[1].asHashtag, "yen") 369 XCTAssertEqual(parsed[2].asText, "¥sign is not allowed") 370 } 371 372 // Test section sign (§) (U+00A7) 373 func testHashtagWithSectionSign() { 374 let parsed = parse_note_content(content: .content("the #section§sign is not allowed",nil)).blocks 375 376 XCTAssertNotNil(parsed) 377 XCTAssertEqual(parsed.count, 3) 378 XCTAssertEqual(parsed[0].asText, "the ") 379 XCTAssertEqual(parsed[1].asHashtag, "section") 380 XCTAssertEqual(parsed[2].asText, "§sign is not allowed") 381 } 382 383 // Test plus-minus sign (±) (U+00B1) 384 func testHashtagWithPlusMinusSign() { 385 let parsed = parse_note_content(content: .content("the #plusminus±sign is not allowed",nil)).blocks 386 387 XCTAssertNotNil(parsed) 388 XCTAssertEqual(parsed.count, 3) 389 XCTAssertEqual(parsed[0].asText, "the ") 390 XCTAssertEqual(parsed[1].asHashtag, "plusminus") 391 XCTAssertEqual(parsed[2].asText, "±sign is not allowed") 392 } 393 394 // Test inverted question mark (¿) (U+00BF) 395 func testHashtagWithInvertedQuestionMark() { 396 let parsed = parse_note_content(content: .content("the #invertedquestion¿mark is not allowed",nil)).blocks 397 398 XCTAssertNotNil(parsed) 399 XCTAssertEqual(parsed.count, 3) 400 XCTAssertEqual(parsed[0].asText, "the ") 401 XCTAssertEqual(parsed[1].asHashtag, "invertedquestion") 402 XCTAssertEqual(parsed[2].asText, "¿mark is not allowed") 403 } 404 405 // Test UTF-8 Latin-1 Supplement Non-Punctuation: U+00C0 to U+00FF (allowed) 406 407 // Test Latin small letter u with diaeresis (ü) (U+00FC) (allowed in hashtags) 408 func testHashtagWithAccents() { 409 let parsed = parse_note_content(content: .content("hello from #türkiye",nil)).blocks 410 411 XCTAssertNotNil(parsed) 412 XCTAssertEqual(parsed.count, 2) 413 XCTAssertEqual(parsed[0].asText, "hello from ") 414 XCTAssertEqual(parsed[1].asHashtag, "türkiye") 415 } 416 417 // Test UTF-8 General Punctuation: U+2000 to U+206F (not allowed in hashtags) 418 419 // Test en dash (–) (U+2013) 420 func testHashtagWithEnDash() { 421 let parsed = parse_note_content(content: .content("the #en–dash is not allowed",nil)).blocks 422 423 XCTAssertNotNil(parsed) 424 XCTAssertEqual(parsed.count, 3) 425 XCTAssertEqual(parsed[0].asText, "the ") 426 XCTAssertEqual(parsed[1].asHashtag, "en") 427 XCTAssertEqual(parsed[2].asText, "–dash is not allowed") 428 } 429 430 // Test em dash (—) (U+2014) 431 func testHashtagWithEmDash() { 432 let parsed = parse_note_content(content: .content("the #em—dash is not allowed",nil)).blocks 433 434 XCTAssertNotNil(parsed) 435 XCTAssertEqual(parsed.count, 3) 436 XCTAssertEqual(parsed[0].asText, "the ") 437 XCTAssertEqual(parsed[1].asHashtag, "em") 438 XCTAssertEqual(parsed[2].asText, "—dash is not allowed") 439 } 440 441 // Test horizontal bar (―) (U+2015) 442 func testHashtagWithHorizontalBar() { 443 let parsed = parse_note_content(content: .content("the #horizontal―bar is not allowed",nil)).blocks 444 445 XCTAssertNotNil(parsed) 446 XCTAssertEqual(parsed.count, 3) 447 XCTAssertEqual(parsed[0].asText, "the ") 448 XCTAssertEqual(parsed[1].asHashtag, "horizontal") 449 XCTAssertEqual(parsed[2].asText, "―bar is not allowed") 450 } 451 452 // Test horizontal ellipsis (…) (U+2026) 453 func testHashtagWithHorizontalEllipsis() { 454 let parsed = parse_note_content(content: .content("the #horizontal…ellipsis is not allowed",nil)).blocks 455 456 XCTAssertNotNil(parsed) 457 XCTAssertEqual(parsed.count, 3) 458 XCTAssertEqual(parsed[0].asText, "the ") 459 XCTAssertEqual(parsed[1].asHashtag, "horizontal") 460 XCTAssertEqual(parsed[2].asText, "…ellipsis is not allowed") 461 } 462 463 // Test UTF-8 Currency Symbols: U+20A0 to U+20CF (not allowed in hashtags) 464 465 // Test euro sign (€) (U+20AC) 466 func testHashtagWithEuroSign() { 467 let parsed = parse_note_content(content: .content("the #euro€sign is not allowed",nil)).blocks 468 469 XCTAssertNotNil(parsed) 470 XCTAssertEqual(parsed.count, 3) 471 XCTAssertEqual(parsed[0].asText, "the ") 472 XCTAssertEqual(parsed[1].asHashtag, "euro") 473 XCTAssertEqual(parsed[2].asText, "€sign is not allowed") 474 } 475 476 // Test Bitcoin sign (₿) (U+20BF) 477 func testHashtagWithBitcoinSign() { 478 let parsed = parse_note_content(content: .content("the #bitcoin₿sign is not allowed",nil)).blocks 479 480 XCTAssertNotNil(parsed) 481 XCTAssertEqual(parsed.count, 3) 482 XCTAssertEqual(parsed[0].asText, "the ") 483 XCTAssertEqual(parsed[1].asHashtag, "bitcoin") 484 XCTAssertEqual(parsed[2].asText, "₿sign is not allowed") 485 } 486 487 // Test UTF-8 Miscellaneous Symbols: U+2600 to U+26FF (allowed in hashtags) 488 489 // Emojis such as ☕️ (U+2615) are allowed in hashtags 490 func testHashtagWithEmoji() { 491 let content = "some hashtag #bitcoin☕️ cool" 492 let parsed = parse_note_content(content: .content(content, nil)).blocks 493 let post_blocks = parse_post_blocks(content: content) 494 495 XCTAssertNotNil(parsed) 496 XCTAssertEqual(parsed.count, 3) 497 XCTAssertEqual(parsed[0].asText, "some hashtag ") 498 XCTAssertEqual(parsed[1].asHashtag, "bitcoin☕️") 499 XCTAssertEqual(parsed[2].asText, " cool") 500 501 XCTAssertEqual(post_blocks.count, 3) 502 XCTAssertEqual(post_blocks[0].asText, "some hashtag ") 503 XCTAssertEqual(post_blocks[1].asHashtag, "bitcoin☕️") 504 XCTAssertEqual(post_blocks[2].asText, " cool") 505 } 506 507 // Test international Unicode (UTF-8) characters 508 509 // Japanese: wave dash (〜) (U+301C) (allowed in hashtags) 510 func testPowHashtag() { 511 let content = "pow! #ぽわ〜" 512 let parsed = parse_note_content(content: .content(content,nil)).blocks 513 let post_blocks = parse_post_blocks(content: content) 514 515 XCTAssertNotNil(parsed) 516 XCTAssertEqual(parsed.count, 2) 517 XCTAssertEqual(parsed[0].asText, "pow! ") 518 XCTAssertEqual(parsed[1].asHashtag, "ぽわ〜") 519 520 XCTAssertEqual(post_blocks.count, 2) 521 XCTAssertEqual(post_blocks[0].asText, "pow! ") 522 XCTAssertEqual(post_blocks[1].asHashtag, "ぽわ〜") 523 } 524 525 // Hangul: Hangul Syllable Si (시) (U+C2DC) and 526 // Hangul Syllable Heom (험) (U+D5D8) (allowed in hashtags) 527 func testHashtagWithNonLatinCharacters() { 528 let parsed = parse_note_content(content: .content("this is a #시험 hope it works",nil)).blocks 529 530 XCTAssertNotNil(parsed) 531 XCTAssertEqual(parsed.count, 3) 532 XCTAssertEqual(parsed[0].asText, "this is a ") 533 XCTAssertEqual(parsed[1].asHashtag, "시험") 534 XCTAssertEqual(parsed[2].asText, " hope it works") 535 } 536 537 // Japanese: fullwidth tilde (~) (U+FF5E) (allowed in hashtags) 538 func testHashtagWithFullwidthTilde() { 539 let parsed = parse_note_content(content: .content("pow! the fullwidth tilde #ぽわ~ is allowed in hashtags",nil)).blocks 540 541 XCTAssertNotNil(parsed) 542 XCTAssertEqual(parsed.count, 3) 543 XCTAssertEqual(parsed[0].asText, "pow! the fullwidth tilde ") 544 XCTAssertEqual(parsed[1].asHashtag, "ぽわ~") 545 XCTAssertEqual(parsed[2].asText, " is allowed in hashtags") 546 } 547 548 // Japanese: bai (倍) (U+500D) (allowed in hashtags) 549 func testHashtagWithBaiKanji() { 550 let parsed = parse_note_content(content: .content("pow! #10倍界王拳 is allowed in hashtags",nil)).blocks 551 552 XCTAssertNotNil(parsed) 553 XCTAssertEqual(parsed.count, 3) 554 XCTAssertEqual(parsed[0].asText, "pow! ") 555 XCTAssertEqual(parsed[1].asHashtag, "10倍界王拳") 556 XCTAssertEqual(parsed[2].asText, " is allowed in hashtags") 557 } 558 559 }