2 var simpleSample
, U_20AC
, poop
, mbSample
,
3 trimByteLength
= require( 'mediawiki.String' ).trimByteLength
;
5 QUnit
.module( 'mediawiki.String.trimByteLength', QUnit
.newMwEnvironment() );
7 // Simple sample (20 chars, 20 bytes)
8 simpleSample
= '12345678901234567890';
10 // 3 bytes (euro-symbol)
13 // Outside of the BMP (pile of poo emoji)
14 poop
= '\uD83D\uDCA9'; // "💩"
16 // Multi-byte sample (22 chars, 26 bytes)
17 mbSample
= '1234567890' + U_20AC
+ '1234567890' + U_20AC
;
20 * Test factory for mw.String#trimByteLength
22 * @param {Object} options
23 * @param {string} options.description Test name
24 * @param {string} options.sample Sequence of characters to trim
25 * @param {string} [options.initial] Previous value of the sequence of characters, if any
26 * @param {Number} options.limit Length to trim to
27 * @param {Function} [options.fn] Filter function
28 * @param {string} options.expected Expected final value
30 function byteLimitTest( options
) {
36 fn: function ( a
) { return a
; },
40 QUnit
.test( opt
.description
, function ( assert
) {
41 var res
= trimByteLength( opt
.initial
, opt
.sample
, opt
.limit
, opt
.fn
);
46 'New value matches the expected string'
52 description
: 'Limit using the maxlength attribute',
55 expected
: '1234567890'
59 description
: 'Limit using a custom value (multibyte)',
62 expected
: '1234567890' + U_20AC
+ '1'
66 description
: 'Limit using a custom value (multibyte, outside BMP)',
73 description
: 'Limit using a custom value (multibyte) overlapping a byte',
76 expected
: '1234567890'
80 description
: 'Pass the limit and a callback as input filter',
82 fn: function ( val
) {
83 var title
= mw
.Title
.newFromText( String( val
) );
84 // Return without namespace prefix
85 return title
? title
.getMain() : '';
87 sample
: 'User:Sample',
88 expected
: 'User:Sample'
92 description
: 'Pass the limit and a callback as input filter',
94 fn: function ( val
) {
95 var title
= mw
.Title
.newFromText( String( val
) );
96 // Return without namespace prefix
97 return title
? title
.getMain() : '';
99 sample
: 'User:Example',
100 // The callback alters the value to be used to calculeate
101 // the length. The altered value is "Exampl" which has
102 // a length of 6, the "e" would exceed the limit.
103 expected
: 'User:Exampl'
107 description
: 'Input filter that increases the length',
109 fn: function ( text
) {
110 return 'prefix' + text
;
112 sample
: simpleSample
,
113 // Prefix adds 6 characters, limit is reached after 4
118 description
: 'Trim from insertion when limit exceeded',
122 // Trim from the insertion point (at 0), not the end
127 description
: 'Trim from insertion when limit exceeded',
131 // Trim from the insertion point (at 1), not the end
136 description
: 'Do not cut up false matching substrings in emoji insertions',
138 initial
: '\uD83D\uDCA9\uD83D\uDCA9', // "💩💩"
139 sample
: '\uD83D\uDCA9\uD83D\uDCB9\uD83E\uDCA9\uD83D\uDCA9', // "💩💹🢩💩"
140 expected
: '\uD83D\uDCA9\uD83D\uDCB9\uD83D\uDCA9' // "💩💹💩"
144 description
: 'Unpaired surrogates do not crash',
146 sample
: '\uD800\uD800\uDFFF',