@@ -470,6 +470,95 @@ void main() {
470470 final japanesePart = result.firstWhere ((r) => r.rawText == 'こんにちは' );
471471 expect (japanesePart.language, equals ('japanese' ));
472472 });
473+
474+ test ('should split mixed Latin and Hangul (abc가나다)' , () {
475+ const input = 'abc가나다' ;
476+ final result = TextRomanizer .analyze (input);
477+
478+ // Expect: [Latin(abc), Hangul(가나다)]
479+ expect (result, hasLength (2 ));
480+
481+ expect (result[0 ].rawText, equals ('abc' ));
482+ expect (result[0 ].language, equals ('empty' ));
483+
484+ expect (result[1 ].rawText, equals ('가나다' ));
485+ expect (result[1 ].language, equals ('korean' ));
486+ });
487+
488+ test ('should split mixed Numbers and Scripts' , () {
489+ // "Room101" -> Room (Latin), 101 (Digits)
490+ const input = 'Room101' ;
491+ final result = TextRomanizer .analyze (input);
492+
493+ expect (result, hasLength (2 ));
494+ expect (result[0 ].rawText, equals ('Room' ));
495+ expect (result[1 ].rawText, equals ('101' ));
496+ });
497+
498+ test ('should NOT split natural Japanese (Kanji + Kana)' , () {
499+ // "日本語です" (Kanji + Hiragana) should stay as ONE chunk
500+ const input = '日本語です' ;
501+ final result = TextRomanizer .analyze (input);
502+
503+ expect (result, hasLength (1 ));
504+ expect (result[0 ].rawText, equals ('日本語です' ));
505+ expect (result[0 ].language, equals ('japanese' ));
506+ });
507+
508+ test ('should handle a complex snippet' , () {
509+ // Input: 123٤٥٦(Numbers)abc가나다(Hangul)カキク(Katakana)
510+ // 123 -> Digits
511+ // ٤٥٦ -> Arabic
512+ // ( -> Separator
513+ // Numbers -> Latin
514+ // ) -> Separator
515+ // abc -> Latin
516+ // 가나다 -> Korean
517+ // ( -> Separator
518+ // Hangul -> Latin
519+ // ) -> Separator
520+ // ... etc
521+
522+ const input = '123٤٥٦(Numbers)abc가나다' ;
523+ final result = TextRomanizer .analyze (input);
524+
525+ // 1. Check "123٤٥٦" split
526+ // ASCII digits [0-9] are separate from Arabic script in the regex
527+ final part123 = result.firstWhere ((r) => r.rawText == '123' );
528+ final partArabicNum = result.firstWhere ((r) => r.rawText == '٤٥٦' );
529+
530+ expect (part123, isNotNull);
531+ expect (partArabicNum, isNotNull);
532+ expect (partArabicNum.language, equals ('arabic' ));
533+
534+ // 2. Check "abc가나다" split
535+ // Find the sequence where abc is followed immediately by 가나다
536+ final indexAbc = result.indexWhere ((r) => r.rawText == 'abc' );
537+ expect (indexAbc, isNot (- 1 ));
538+
539+ final partKorean = result[indexAbc + 1 ];
540+ expect (partKorean.rawText, equals ('가나다' ));
541+ expect (partKorean.language, equals ('korean' ));
542+ });
543+
544+ test ('should split CJK vs Latin' , () {
545+ const input = 'Hello你好' ;
546+ final result = TextRomanizer .analyze (input);
547+
548+ expect (result, hasLength (2 ));
549+ expect (result[0 ].rawText, equals ('Hello' ));
550+ expect (result[1 ].rawText, equals ('你好' ));
551+ });
552+
553+ test ('should split Cyrillic vs Latin' , () {
554+ const input = 'TestТест' ; // Latin 'Test', Cyrillic 'Test'
555+ final result = TextRomanizer .analyze (input);
556+
557+ expect (result, hasLength (2 ));
558+ expect (result[0 ].rawText, equals ('Test' ));
559+ expect (result[1 ].rawText, equals ('Тест' ));
560+ expect (result[1 ].language, equals ('cyrillic' ));
561+ });
473562 });
474563
475564 group ('supportedLanguages' , () {
0 commit comments