@@ -12,82 +12,78 @@ const readline = require('internal/readline/utils');
12
12
13
13
// Ll (Lowercase Letter): LATIN SMALL LETTER A
14
14
assert . strictEqual ( readline . getStringWidth ( 'a' ) , 1 ) ;
15
- assert . strictEqual ( readline . getStringWidth ( 0x0061 ) , 1 ) ;
15
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x0061 ) ) , 1 ) ;
16
16
// Lo (Other Letter)
17
17
assert . strictEqual ( readline . getStringWidth ( '丁' ) , 2 ) ;
18
- assert . strictEqual ( readline . getStringWidth ( 0x4E01 ) , 2 ) ;
18
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x4E01 ) ) , 2 ) ;
19
19
// Surrogate pairs
20
- assert . strictEqual ( readline . getStringWidth ( '\ud83d\udc78\ud83c\udfff' ) , 2 ) ;
20
+ assert . strictEqual ( readline . getStringWidth ( '\ud83d\udc78\ud83c\udfff' ) , 4 ) ;
21
21
assert . strictEqual ( readline . getStringWidth ( '👅' ) , 2 ) ;
22
22
// Cs (Surrogate): High Surrogate
23
23
assert . strictEqual ( readline . getStringWidth ( '\ud83d' ) , 1 ) ;
24
24
// Cs (Surrogate): Low Surrogate
25
25
assert . strictEqual ( readline . getStringWidth ( '\udc78' ) , 1 ) ;
26
26
// Cc (Control): NULL
27
- assert . strictEqual ( readline . getStringWidth ( 0 ) , 0 ) ;
27
+ assert . strictEqual ( readline . getStringWidth ( '\u0000' ) , 0 ) ;
28
28
// Cc (Control): BELL
29
- assert . strictEqual ( readline . getStringWidth ( 0x0007 ) , 0 ) ;
29
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x0007 ) ) , 0 ) ;
30
30
// Cc (Control): LINE FEED
31
31
assert . strictEqual ( readline . getStringWidth ( '\n' ) , 0 ) ;
32
32
// Cf (Format): SOFT HYPHEN
33
- assert . strictEqual ( readline . getStringWidth ( 0x00AD ) , 1 ) ;
33
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x00AD ) ) , 1 ) ;
34
34
// Cf (Format): LEFT-TO-RIGHT MARK
35
35
// Cf (Format): RIGHT-TO-LEFT MARK
36
36
assert . strictEqual ( readline . getStringWidth ( '\u200Ef\u200F' ) , 1 ) ;
37
37
// Cn (Unassigned): Not a character
38
- assert . strictEqual ( readline . getStringWidth ( 0x10FFEF ) , 1 ) ;
38
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x10FFEF ) ) , 1 ) ;
39
39
// Cn (Unassigned): Not a character (but in a CJK range)
40
- assert . strictEqual ( readline . getStringWidth ( 0x3FFEF ) , 2 ) ;
40
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x3FFEF ) ) , 1 ) ;
41
41
// Mn (Nonspacing Mark): COMBINING ACUTE ACCENT
42
- assert . strictEqual ( readline . getStringWidth ( 0x0301 ) , 0 ) ;
42
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x0301 ) ) , 0 ) ;
43
43
// Mc (Spacing Mark): BALINESE ADEG ADEG
44
44
// Chosen as its Canonical_Combining_Class is not 0, but is not a 0-width
45
45
// character.
46
- assert . strictEqual ( readline . getStringWidth ( 0x1B44 ) , 1 ) ;
46
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x1B44 ) ) , 1 ) ;
47
47
// Me (Enclosing Mark): COMBINING ENCLOSING CIRCLE
48
- assert . strictEqual ( readline . getStringWidth ( 0x20DD ) , 0 ) ;
48
+ assert . strictEqual ( readline . getStringWidth ( String . fromCharCode ( 0x20DD ) ) , 0 ) ;
49
49
50
- // The following is an emoji sequence. In some implementations, it is
51
- // represented as a single glyph, in other implementations as a sequence
52
- // of individual glyphs. By default, the algorithm will assume the single
53
- // glyph interpretation and return a value of 2. By passing the
54
- // expandEmojiSequence: true option, each component will be counted
55
- // individually.
56
- assert . strictEqual ( readline . getStringWidth ( '👩👩👧👧' ) , 2 ) ;
57
- assert . strictEqual (
58
- readline . getStringWidth ( '👩👩👧👧' , { expandEmojiSequence : true } ) , 8 ) ;
50
+ // The following is an emoji sequence with ZWJ (zero-width-joiner). In some
51
+ // implementations, it is represented as a single glyph, in other
52
+ // implementations as a sequence of individual glyphs. By default, each
53
+ // component will be counted individually, since not a lot of systems support
54
+ // these fully.
55
+ // See https://www.unicode.org/reports/tr51/tr51-16.html#Emoji_ZWJ_Sequences
56
+ assert . strictEqual ( readline . getStringWidth ( '👩👩👧👧' ) , 8 ) ;
57
+ // TODO(BridgeAR): This should have a width of two and six. The heart contains
58
+ // the \uFE0F variation selector that indicates that it should be displayed as
59
+ // emoji instead of as text. Emojis are all full width characters when not being
60
+ // rendered as text.
61
+ // https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block)
62
+ assert . strictEqual ( readline . getStringWidth ( '❤️' ) , 1 ) ;
63
+ assert . strictEqual ( readline . getStringWidth ( '👩❤️👩' ) , 5 ) ;
64
+ // The length of one is correct. It is an emoji treated as text.
65
+ assert . strictEqual ( readline . getStringWidth ( '❤' ) , 1 ) ;
59
66
60
67
// By default, unicode characters whose width is considered ambiguous will
61
68
// be considered half-width. For these characters, getStringWidth will return
62
69
// 1. In some contexts, however, it is more appropriate to consider them full
63
- // width. By default, the algorithm will assume half width. By passing
64
- // the ambiguousAsFullWidth: true option, ambiguous characters will be counted
65
- // as 2 columns.
70
+ // width. By default, the algorithm will assume half width.
66
71
assert . strictEqual ( readline . getStringWidth ( '\u01d4' ) , 1 ) ;
67
- assert . strictEqual (
68
- readline . getStringWidth ( '\u01d4' , { ambiguousAsFullWidth : true } ) , 2 ) ;
69
72
70
73
// Control chars and combining chars are zero
71
74
assert . strictEqual ( readline . getStringWidth ( '\u200E\n\u220A\u20D2' ) , 1 ) ;
72
75
73
76
// Test that the fast path for ASCII characters yields results consistent
74
77
// with the 'slow' path.
75
- for ( const ambiguousAsFullWidth of [ false , true ] ) {
76
- for ( let i = 0 ; i < 256 ; i ++ ) {
77
- const char = String . fromCharCode ( i ) ;
78
- assert . strictEqual (
79
- readline . getStringWidth ( i , { ambiguousAsFullWidth } ) ,
80
- readline . getStringWidth ( char , { ambiguousAsFullWidth } ) ) ;
81
- assert . strictEqual (
82
- readline . getStringWidth ( char + '🎉' , { ambiguousAsFullWidth } ) ,
83
- readline . getStringWidth ( char , { ambiguousAsFullWidth } ) + 2 ) ;
78
+ for ( let i = 0 ; i < 256 ; i ++ ) {
79
+ const char = String . fromCharCode ( i ) ;
80
+ assert . strictEqual (
81
+ readline . getStringWidth ( char + '🎉' ) ,
82
+ readline . getStringWidth ( char ) + 2 ) ;
84
83
85
- if ( i < 32 || ( i >= 127 && i < 160 ) ) { // Control character
86
- assert . strictEqual (
87
- readline . getStringWidth ( i , { ambiguousAsFullWidth } ) , 0 ) ;
88
- } else if ( i < 127 ) { // Regular ASCII character
89
- assert . strictEqual (
90
- readline . getStringWidth ( i , { ambiguousAsFullWidth } ) , 1 ) ;
91
- }
84
+ if ( i < 32 || ( i >= 127 && i < 160 ) ) { // Control character
85
+ assert . strictEqual ( readline . getStringWidth ( char ) , 0 ) ;
86
+ } else { // Regular ASCII character
87
+ assert . strictEqual ( readline . getStringWidth ( char ) , 1 ) ;
92
88
}
93
89
}
0 commit comments