2 var simpleSample
, U_20AC
, mbSample
;
4 QUnit
.module( 'jquery.byteLimit', QUnit
.newMwEnvironment() );
6 // Simple sample (20 chars, 20 bytes)
7 simpleSample
= '12345678901234567890';
9 // 3 bytes (euro-symbol)
12 // Multi-byte sample (22 chars, 26 bytes)
13 mbSample
= '1234567890' + U_20AC
+ '1234567890' + U_20AC
;
15 // Basic sendkey-implementation
16 function addChars( $input
, charstr
) {
17 var len
, i
, prevVal
, code
, event
;
19 for ( i
= 0; i
< len
; i
+= 1 ) {
20 // Keep track of the previous value
21 prevVal
= $input
.val();
24 code
= charstr
.charCodeAt( i
);
26 // Trigger event and undo if prevented
27 event
= new jQuery
.Event( 'keypress', {
32 $input
.trigger( event
);
33 if ( !event
.isDefaultPrevented() ) {
34 $input
.val( prevVal
+ charstr
.charAt( i
) );
40 * Test factory for $.fn.byteLimit
42 * @param $input {jQuery} jQuery object in an input element
43 * @param hasLimit {Boolean} Wether a limit should apply at all
44 * @param limit {Number} Limit (if used) otherwise undefined
45 * The limit should be less than 20 (the sample data's length)
47 function byteLimitTest( options
) {
57 QUnit
.test( opt
.description
, function ( assert
) {
58 var rawVal
, fn
, newVal
;
60 opt
.$input
.appendTo( '#qunit-fixture' );
62 // Simulate pressing keys for each of the sample characters
63 addChars( opt
.$input
, opt
.sample
);
64 rawVal
= opt
.$input
.val();
65 fn
= opt
.$input
.data( 'byteLimit-callback' );
66 newVal
= $.isFunction( fn
) ? fn( rawVal
) : rawVal
;
72 $.byteLength( newVal
),
74 'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
77 $.byteLength( rawVal
),
78 $.byteLength( opt
.expected
),
79 'Not preventing keypresses too early, length has reached the expected length'
81 assert
.equal( rawVal
, opt
.expected
, 'New value matches the expected string' );
85 assert
.equal( newVal
, opt
.expected
, 'New value matches the expected string' );
87 $.byteLength( newVal
),
88 $.byteLength( opt
.expected
),
89 'Unlimited scenarios are not affected, expected length reached'
96 description
: 'Plain text input',
97 $input
: $( '<input>' )
98 .attr( 'type', 'text' ),
101 expected
: simpleSample
105 description
: 'Plain text input. Calling byteLimit with no parameters and no maxLength property (bug 36310)',
106 $input
: $( '<input>' )
107 .attr( 'type', 'text' )
109 sample
: simpleSample
,
111 expected
: simpleSample
115 description
: 'Limit using the maxlength attribute',
116 $input
: $( '<input>' )
117 .attr( 'type', 'text' )
118 .prop( 'maxLength', '10' )
120 sample
: simpleSample
,
123 expected
: '1234567890'
127 description
: 'Limit using a custom value',
128 $input
: $( '<input>' )
129 .attr( 'type', 'text' )
131 sample
: simpleSample
,
134 expected
: '1234567890'
138 description
: 'Limit using a custom value, overriding maxlength attribute',
139 $input
: $( '<input>' )
140 .attr( 'type', 'text' )
141 .prop( 'maxLength', '10' )
143 sample
: simpleSample
,
146 expected
: '123456789012345'
150 description
: 'Limit using a custom value (multibyte)',
151 $input
: $( '<input>' )
152 .attr( 'type', 'text' )
157 expected
: '1234567890' + U_20AC
+ '1'
161 description
: 'Limit using a custom value (multibyte) overlapping a byte',
162 $input
: $( '<input>' )
163 .attr( 'type', 'text' )
168 expected
: '1234567890' + '12'
172 description
: 'Pass the limit and a callback as input filter',
173 $input
: $( '<input>' )
174 .attr( 'type', 'text' )
175 .byteLimit( 6, function ( val
) {
181 // Return without namespace prefix
182 return new mw
.Title( String( val
) ).getMain();
184 sample
: 'User:Sample',
186 limit
: 6, // 'Sample' length
187 expected
: 'User:Sample'
191 description
: 'Limit using the maxlength attribute and pass a callback as input filter',
192 $input
: $( '<input>' )
193 .attr( 'type', 'text' )
194 .prop( 'maxLength', '6' )
195 .byteLimit( function ( val
) {
201 // Return without namespace prefix
202 return new mw
.Title( String( val
) ).getMain();
204 sample
: 'User:Sample',
206 limit
: 6, // 'Sample' length
207 expected
: 'User:Sample'
210 QUnit
.test( 'Confirm properties and attributes set', 5, function ( assert
) {
214 .attr( 'type', 'text' )
215 .prop( 'maxLength', '7' )
216 .appendTo( '#qunit-fixture' )
219 assert
.strictEqual( $el
.prop( 'maxLength' ), 7, 'Pre-set maxLength property unchanged' );
222 .attr( 'type', 'text' )
223 .prop( 'maxLength', '7' )
224 .appendTo( '#qunit-fixture' )
227 assert
.strictEqual( $el
.prop( 'maxLength' ), 12, 'maxLength property updated if value was passed to $.fn.byteLimit' );
229 $elA
= $( '<input>' )
230 .addClass( 'mw-test-byteLimit-foo' )
231 .attr( 'type', 'text' )
232 .prop( 'maxLength', '7' )
233 .appendTo( '#qunit-fixture' );
235 $elB
= $( '<input>' )
236 .addClass( 'mw-test-byteLimit-foo' )
237 .attr( 'type', 'text' )
238 .prop( 'maxLength', '12' )
239 .appendTo( '#qunit-fixture' );
241 $el
= $( '.mw-test-byteLimit-foo' );
243 assert
.strictEqual( $el
.length
, 2, 'Verify that there are no other elements clashing with this test suite' );
247 // Before bug 35294 was fixed, both $elA and $elB had maxLength set to 7,
248 // because $.fn.byteLimit sets:
249 // `limit = limitArg || this.prop( 'maxLength' ); this.prop( 'maxLength', limit )`
250 // and did so outside the each() loop.
251 assert
.strictEqual( $elA
.prop( 'maxLength' ), 7, 'maxLength was not incorrectly set on #1 when calling byteLimit on multiple elements (bug 35294)' );
252 assert
.strictEqual( $elB
.prop( 'maxLength' ), 12, 'maxLength was not incorrectly set on #2 when calling byteLimit on multiple elements (bug 35294)' );