@@ -569,6 +569,193 @@ describe('strings', () => {
569569 it ( 'should handle mixed everything' , ( ) => {
570570 expect ( toKebabCase ( 'get_HTML5_Document' ) ) . toBe ( 'get-html5-document' )
571571 } )
572+
573+ it ( 'should handle empty string early return' , ( ) => {
574+ // Tests line 731: if (!str.length)
575+ const result = toKebabCase ( '' )
576+ expect ( result ) . toBe ( '' )
577+ } )
578+ } )
579+
580+ describe ( 'camelToKebab additional edge cases' , ( ) => {
581+ it ( 'should handle break condition in inner loop' , ( ) => {
582+ // Tests lines 111-112: if (!char) break
583+ expect ( camelToKebab ( 'Test' ) ) . toBe ( 'test' )
584+ } )
585+
586+ it ( 'should handle uppercase sequence collection' , ( ) => {
587+ // Tests lines 124-140: consecutive uppercase handling
588+ expect ( camelToKebab ( 'XMLHTTPRequest' ) ) . toBe ( 'xmlhttprequest' )
589+ expect ( camelToKebab ( 'IOError' ) ) . toBe ( 'ioerror' )
590+ } )
591+
592+ it ( 'should handle non-uppercase continuation' , ( ) => {
593+ // Tests lines 136-139: stop when hitting non-uppercase
594+ expect ( camelToKebab ( 'HTTPSConnection' ) ) . toBe ( 'httpsconnection' )
595+ } )
596+
597+ it ( 'should handle mixed case with numbers' , ( ) => {
598+ // Tests lines 141-145: lowercase letters, digits, other chars
599+ expect ( camelToKebab ( 'base64Encode' ) ) . toBe ( 'base64-encode' )
600+ expect ( camelToKebab ( 'sha256Hash' ) ) . toBe ( 'sha256-hash' )
601+ } )
602+ } )
603+
604+ describe ( 'search additional edge cases' , ( ) => {
605+ it ( 'should return -1 when fromIndex >= length' , ( ) => {
606+ // Tests line 311-312: if (fromIndex >= length)
607+ const result = search ( 'hello' , / l / , { fromIndex : 10 } )
608+ expect ( result ) . toBe ( - 1 )
609+ } )
610+
611+ it ( 'should use fast path when fromIndex === 0' , ( ) => {
612+ // Tests line 314-315: if (fromIndex === 0)
613+ const result = search ( 'hello world' , / w o r l d / , { fromIndex : 0 } )
614+ expect ( result ) . toBe ( 6 )
615+ } )
616+ } )
617+
618+ describe ( 'stringWidth edge cases' , ( ) => {
619+ it ( 'should return 0 for non-string input' , ( ) => {
620+ // Tests line 546-547: typeof check and !text.length
621+ // @ts -expect-error - testing runtime behavior
622+ expect ( stringWidth ( null ) ) . toBe ( 0 )
623+ // @ts -expect-error - testing runtime behavior
624+ expect ( stringWidth ( undefined ) ) . toBe ( 0 )
625+ // @ts -expect-error - testing runtime behavior
626+ expect ( stringWidth ( 123 ) ) . toBe ( 0 )
627+ } )
628+
629+ it ( 'should return 0 for empty string' , ( ) => {
630+ // Tests line 546-547
631+ expect ( stringWidth ( '' ) ) . toBe ( 0 )
632+ } )
633+
634+ it ( 'should return 0 for string with only ANSI codes' , ( ) => {
635+ // Tests line 555-556: plainText.length check
636+ expect ( stringWidth ( '\x1b[31m\x1b[0m' ) ) . toBe ( 0 )
637+ } )
638+
639+ it ( 'should skip zero-width clusters' , ( ) => {
640+ // Tests line 604-605: zeroWidthClusterRegex
641+ expect ( stringWidth ( 'hello\u200Bworld' ) ) . toBe ( 10 ) // Zero-width space
642+ expect ( stringWidth ( 'test\t' ) ) . toBe ( 4 ) // Tab is control char
643+ } )
644+
645+ it ( 'should handle RGI emoji as double-width' , ( ) => {
646+ // Tests line 623-625: emojiRegex
647+ expect ( stringWidth ( '👍' ) ) . toBeGreaterThanOrEqual ( 2 )
648+ expect ( stringWidth ( '😀' ) ) . toBeGreaterThanOrEqual ( 2 )
649+ } )
650+
651+ it ( 'should use East Asian Width for non-emoji' , ( ) => {
652+ // Tests line 639-640: baseSegment and codePointAt
653+ expect ( stringWidth ( '漢' ) ) . toBeGreaterThanOrEqual ( 2 ) // CJK
654+ expect ( stringWidth ( 'ア' ) ) . toBe ( 1 ) // Halfwidth Katakana
655+ } )
656+
657+ it ( 'should handle trailing halfwidth/fullwidth forms' , ( ) => {
658+ // Tests line 678-690: segment.length > 1 and charCode checks
659+ const textWithHalfwidth = 'a゙' // 'a' + halfwidth dakuten
660+ expect ( stringWidth ( textWithHalfwidth ) ) . toBeGreaterThanOrEqual ( 1 )
661+ } )
662+ } )
663+
664+ describe ( 'trimNewlines comprehensive edge cases' , ( ) => {
665+ it ( 'should return empty string for length 0' , ( ) => {
666+ // Tests line 780-781: if (length === 0)
667+ expect ( trimNewlines ( '' ) ) . toBe ( '' )
668+ } )
669+
670+ it ( 'should handle single newline character' , ( ) => {
671+ // Tests line 785-786: if (length === 1) with newline
672+ expect ( trimNewlines ( '\n' ) ) . toBe ( '' )
673+ expect ( trimNewlines ( '\r' ) ) . toBe ( '' )
674+ } )
675+
676+ it ( 'should handle single non-newline character' , ( ) => {
677+ // Tests line 785-786: if (length === 1) with non-newline
678+ expect ( trimNewlines ( 'a' ) ) . toBe ( 'a' )
679+ } )
680+
681+ it ( 'should return original if no edge newlines' , ( ) => {
682+ // Tests line 790-791: noFirstNewline && noLastNewline
683+ expect ( trimNewlines ( 'hello' ) ) . toBe ( 'hello' )
684+ expect ( trimNewlines ( 'a\nb' ) ) . toBe ( 'a\nb' )
685+ } )
686+
687+ it ( 'should handle newlines at start' , ( ) => {
688+ // Tests line 795-800: while loop for start
689+ expect ( trimNewlines ( '\n\r\nhello' ) ) . toBe ( 'hello' )
690+ } )
691+
692+ it ( 'should handle newlines at end' , ( ) => {
693+ // Tests line 802-807: while loop for end
694+ expect ( trimNewlines ( 'hello\r\n\n' ) ) . toBe ( 'hello' )
695+ } )
696+
697+ it ( 'should handle newlines at both ends' , ( ) => {
698+ // Tests both loops
699+ expect ( trimNewlines ( '\r\n\rhello\n\r' ) ) . toBe ( 'hello' )
700+ } )
701+ } )
702+
703+ describe ( 'centerText edge cases' , ( ) => {
704+ it ( 'should return original text when >= width' , ( ) => {
705+ // Tests line 882: if (textLength >= width)
706+ expect ( centerText ( 'hello' , 5 ) ) . toBe ( 'hello' )
707+ expect ( centerText ( 'hello' , 3 ) ) . toBe ( 'hello' )
708+ expect ( centerText ( 'longer text' , 5 ) ) . toBe ( 'longer text' )
709+ } )
710+
711+ it ( 'should center text with odd padding' , ( ) => {
712+ // Tests padding calculation
713+ expect ( centerText ( 'hi' , 5 ) ) . toBe ( ' hi ' )
714+ expect ( centerText ( 'a' , 7 ) ) . toBe ( ' a ' )
715+ } )
716+
717+ it ( 'should center text with even padding' , ( ) => {
718+ expect ( centerText ( 'test' , 8 ) ) . toBe ( ' test ' )
719+ } )
720+ } )
721+
722+ describe ( 'indentString edge cases' , ( ) => {
723+ it ( 'should handle empty lines correctly' , ( ) => {
724+ // Tests line 186-187: regex with empty line handling
725+ const result = indentString ( 'line1\n\nline3' , { count : 2 } )
726+ expect ( result ) . toBe ( ' line1\n\n line3' )
727+ } )
728+
729+ it ( 'should use default count of 1' , ( ) => {
730+ const result = indentString ( 'hello' )
731+ expect ( result ) . toBe ( ' hello' )
732+ } )
733+
734+ it ( 'should handle large count values' , ( ) => {
735+ const result = indentString ( 'test' , { count : 10 } )
736+ expect ( result ) . toBe ( `${ ' ' . repeat ( 10 ) } test` )
737+ } )
738+ } )
739+
740+ describe ( 'isBlankString edge cases' , ( ) => {
741+ it ( 'should handle various whitespace types' , ( ) => {
742+ // Tests line 223: /^\s+$/.test(value)
743+ expect ( isBlankString ( ' \t\n\r ' ) ) . toBe ( true )
744+ expect ( isBlankString ( '\n\n\n' ) ) . toBe ( true )
745+ expect ( isBlankString ( '\t\t\t' ) ) . toBe ( true )
746+ } )
747+
748+ it ( 'should return false for non-blank strings' , ( ) => {
749+ expect ( isBlankString ( ' a ' ) ) . toBe ( false )
750+ expect ( isBlankString ( ' \n x ' ) ) . toBe ( false )
751+ } )
752+
753+ it ( 'should handle non-string types' , ( ) => {
754+ expect ( isBlankString ( null ) ) . toBe ( false )
755+ expect ( isBlankString ( undefined ) ) . toBe ( false )
756+ expect ( isBlankString ( 123 ) ) . toBe ( false )
757+ expect ( isBlankString ( { } ) ) . toBe ( false )
758+ } )
572759 } )
573760 } )
574761} )
0 commit comments