@@ -37,6 +37,10 @@ test('ignores control characters', t => {
3737
3838test ( 'handles combining characters' , t => {
3939 t . is ( stringWidth ( 'x\u0300' ) , 1 ) ;
40+ t . is ( stringWidth ( '\u0300\u0301' ) , 0 ) ;
41+ t . is ( stringWidth ( 'e\u0301e' ) , 2 ) ;
42+ t . is ( stringWidth ( 'x\u036F' ) , 1 ) ;
43+ t . is ( stringWidth ( '\u036F\u036F' ) , 0 ) ;
4044} ) ;
4145
4246test ( 'handles ZWJ characters' , t => {
@@ -45,3 +49,52 @@ test('handles ZWJ characters', t => {
4549 t . is ( stringWidth ( '👩👩👦👦' ) , 2 ) ;
4650 t . is ( stringWidth ( '👨❤️💋👨' ) , 2 ) ;
4751} ) ;
52+
53+ test ( 'handles zero-width characters' , t => {
54+ t . is ( stringWidth ( '\u200B' ) , 0 ) ;
55+ t . is ( stringWidth ( 'x\u200Bx' ) , 2 ) ;
56+ t . is ( stringWidth ( '\u200C' ) , 0 ) ;
57+ t . is ( stringWidth ( 'x\u200Cx' ) , 2 ) ;
58+ t . is ( stringWidth ( '\u200D' ) , 0 ) ;
59+ t . is ( stringWidth ( 'x\u200Dx' ) , 2 ) ;
60+ t . is ( stringWidth ( '\uFEFF' ) , 0 ) ;
61+ t . is ( stringWidth ( 'x\uFEFFx' ) , 2 ) ;
62+ } ) ;
63+
64+ test ( 'handles surrogate pairs' , t => {
65+ t . is ( stringWidth ( '\uD83D\uDE00' ) , 2 ) ; // 😀
66+ t . is ( stringWidth ( 'A\uD83D\uDE00B' ) , 4 ) ;
67+ } ) ;
68+
69+ test ( 'handles variation selectors' , t => {
70+ t . is ( stringWidth ( '\u{1F1E6}\uFE0F' ) , 1 ) ; // Regional indicator symbol A with variation selector
71+ t . is ( stringWidth ( 'A\uFE0F' ) , 1 ) ;
72+ t . is ( stringWidth ( '\uFE0F' ) , 0 ) ;
73+ } ) ;
74+
75+ test ( 'handles edge cases' , t => {
76+ t . is ( stringWidth ( '' ) , 0 ) ;
77+ t . is ( stringWidth ( '\u200B\u200B' ) , 0 ) ;
78+ t . is ( stringWidth ( 'x\u200Bx\u200B' ) , 2 ) ;
79+ t . is ( stringWidth ( 'x\u0300x\u0300' ) , 2 ) ;
80+ t . is ( stringWidth ( '\uD83D\uDE00\uFE0F' ) , 2 ) ; // 😀 with variation selector
81+ t . is ( stringWidth ( '\uD83D\uDC69\u200D\uD83C\uDF93' ) , 2 ) ; // 👩🎓
82+ t . is ( stringWidth ( 'x\u1AB0x\u1AB0' ) , 2 ) ; // Combining diacritical marks extended
83+ t . is ( stringWidth ( 'x\u1DC0x\u1DC0' ) , 2 ) ; // Combining diacritical marks supplement
84+ t . is ( stringWidth ( 'x\u20D0x\u20D0' ) , 2 ) ; // Combining diacritical marks for symbols
85+ t . is ( stringWidth ( 'x\uFE20x\uFE20' ) , 2 ) ; // Combining half marks
86+ } ) ;
87+
88+ test ( 'ignores default ignorable code points' , t => {
89+ t . is ( stringWidth ( '\u2060' ) , 0 ) ; // Word joiner
90+ t . is ( stringWidth ( '\u2061' ) , 0 ) ; // Function application
91+ t . is ( stringWidth ( '\u2062' ) , 0 ) ; // Invisible times
92+ t . is ( stringWidth ( '\u2063' ) , 0 ) ; // Invisible separator
93+ t . is ( stringWidth ( '\u2064' ) , 0 ) ; // Invisible plus
94+ t . is ( stringWidth ( '\uFEFF' ) , 0 ) ; // Zero-width no-break space
95+ t . is ( stringWidth ( 'x\u2060x' ) , 2 ) ;
96+ t . is ( stringWidth ( 'x\u2061x' ) , 2 ) ;
97+ t . is ( stringWidth ( 'x\u2062x' ) , 2 ) ;
98+ t . is ( stringWidth ( 'x\u2063x' ) , 2 ) ;
99+ t . is ( stringWidth ( 'x\u2064x' ) , 2 ) ;
100+ } ) ;
0 commit comments