Page MenuHomeWickedGov Phorge

jquery.lengthLimit.test.js
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

jquery.lengthLimit.test.js

QUnit.module( 'jquery.lengthLimit', () => {
// Simple sample (20 chars, 20 bytes)
const simpleSample = '12345678901234567890';
// 3 bytes (euro-symbol)
const U_20AC = '\u20AC';
// Outside of the BMP (pile of poo emoji)
const poop = '\uD83D\uDCA9'; // "💩"
// Multi-byte sample (22 chars, 26 bytes)
const mbSample = '1234567890' + U_20AC + '1234567890' + U_20AC;
// Basic sendkey-implementation
function addChars( $input, charstr ) {
function x( $el, i ) {
// Add character to the value
return $el.val() + charstr.charAt( i );
}
for ( let c = 0; c < charstr.length; c++ ) {
$input
.val( x( $input, c ) )
.trigger( 'change' );
}
}
QUnit.test.each( 'byteLimit()', {
'Plain text input': {
$input: $( '<input>' ).attr( 'type', 'text' ),
sample: simpleSample,
expected: simpleSample
},
'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (T38310)': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit(),
sample: simpleSample,
expected: simpleSample
},
'Limit using the maxlength attribute': {
$input: $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '10' )
.byteLimit(),
sample: simpleSample,
expected: '1234567890'
},
'Limit using a custom value': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 10 ),
sample: simpleSample,
expected: '1234567890'
},
'Limit using a custom value, overriding maxlength attribute': {
$input: $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '10' )
.byteLimit( 15 ),
sample: simpleSample,
expected: '123456789012345'
},
'Limit using a custom value (multibyte)': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 14 ),
sample: mbSample,
expected: '1234567890' + U_20AC + '1'
},
'Limit using a custom value (multibyte, outside BMP)': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 3 ),
sample: poop,
expected: ''
},
'Limit using a custom value (multibyte) overlapping a byte': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 12 ),
sample: mbSample,
expected: '123456789012'
},
'Pass the limit and a callback as input filter': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 6, ( val ) => {
const title = mw.Title.newFromText( String( val ) );
// Return without namespace prefix
return title ? title.getMain() : '';
} ),
sample: 'User:Sample',
expected: 'User:Sample'
},
'Limit using the maxlength attribute and pass a callback as input filter': {
$input: $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '6' )
.byteLimit( ( val ) => {
const title = mw.Title.newFromText( String( val ) );
// Return without namespace prefix
return title ? title.getMain() : '';
} ),
sample: 'User:Sample',
expected: 'User:Sample'
},
'Truncate with exceeded limit and filter callback': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 6, ( val ) => {
const title = mw.Title.newFromText( String( val ) );
// Return without namespace prefix
return title ? title.getMain() : '';
} ),
sample: 'User:Example',
// The callback alters the value to be used to calculeate
// the length. The altered value is "Exampl" which has
// a length of 6, the "e" would exceed the limit.
expected: 'User:Exampl'
},
'Input filter that increases the length': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 10, ( text ) => 'prefix' + text ),
sample: simpleSample,
// Prefix adds 6 characters, limit is reached after 4
expected: '1234'
},
// Regression tests for T43450
'Input filter of which the base exceeds the limit': {
$input: $( '<input>' ).attr( 'type', 'text' )
.byteLimit( 3, ( text ) => 'prefix' + text ),
sample: simpleSample,
expected: ''
},
'Unpaired surrogates do not crash': {
$input: $( '<input>' ).attr( 'type', 'text' ).byteLimit( 4 ),
sample: '\uD800\uD800\uDFFF',
expected: '\uD800'
}
}, ( assert, opt ) => {
opt.$input.appendTo( '#qunit-fixture' );
// Simulate pressing keys for each of the sample characters
addChars( opt.$input, opt.sample );
assert.strictEqual(
opt.$input.val(),
opt.expected,
'New value matches the expected string'
);
} );
QUnit.test( 'Confirm properties and attributes set', ( assert ) => {
let $el;
$el = $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' )
.byteLimit();
assert.strictEqual( $el.attr( 'maxlength' ), '7', 'maxlength attribute unchanged for simple limit' );
$el = $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' )
.byteLimit( 12 );
assert.strictEqual( $el.attr( 'maxlength' ), '12', 'maxlength attribute updated for custom limit' );
$el = $( '<input>' ).attr( 'type', 'text' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' )
.byteLimit( 12, ( val ) => val );
assert.strictEqual( $el.attr( 'maxlength' ), undefined, 'maxlength attribute removed for limit with callback' );
$( '<input>' ).attr( 'type', 'text' )
.addClass( 'mw-test-byteLimit-foo' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' );
$( '<input>' ).attr( 'type', 'text' )
.addClass( 'mw-test-byteLimit-foo' )
.attr( 'maxlength', '12' )
.appendTo( '#qunit-fixture' );
$el = $( '.mw-test-byteLimit-foo' );
assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
$el.byteLimit();
} );
QUnit.test( 'Trim from insertion when limit exceeded', ( assert ) => {
let $el;
// Use a new <input> because the bug only occurs on the first time
// the limit it reached (T42850)
$el = $( '<input>' ).attr( 'type', 'text' )
.appendTo( '#qunit-fixture' )
.byteLimit( 3 )
.val( 'abc' ).trigger( 'change' )
.val( 'zabc' ).trigger( 'change' );
assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 0), not the end' );
$el = $( '<input>' ).attr( 'type', 'text' )
.appendTo( '#qunit-fixture' )
.byteLimit( 3 )
.val( 'abc' ).trigger( 'change' )
.val( 'azbc' ).trigger( 'change' );
assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 1), not the end' );
} );
QUnit.test( 'Do not cut up false matching substrings in emoji insertions', ( assert ) => {
const oldVal = '\uD83D\uDCA9\uD83D\uDCA9', // "💩💩"
newVal = '\uD83D\uDCA9\uD83D\uDCB9\uD83E\uDCA9\uD83D\uDCA9', // "💩💹🢩💩"
expected = '\uD83D\uDCA9\uD83D\uDCB9\uD83D\uDCA9'; // "💩💹💩"
// Possible bad results:
// * With no surrogate support:
// '\uD83D\uDCA9\uD83D\uDCB9\uD83E\uDCA9' "💩💹🢩"
// * With correct trimming but bad detection of inserted text:
// '\uD83D\uDCA9\uD83D\uDCB9\uDCA9' "💩💹�"
const $el = $( '<input>' ).attr( 'type', 'text' )
.appendTo( '#qunit-fixture' )
.byteLimit( 12 )
.val( oldVal ).trigger( 'change' )
.val( newVal ).trigger( 'change' );
assert.strictEqual( $el.val(), expected, 'Pasted emoji correctly trimmed at the end' );
} );
} );

File Metadata

Mime Type
text/x-asm
Expires
Sat, May 16, 21:50 (1 d, 6 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
68/ef/8763e84c3e6c2e2d9beef5d11816
Default Alt Text
jquery.lengthLimit.test.js (7 KB)

Event Timeline