Merge "Fix API output formatting (change lines delimited with * as bold)"
[lhc/web/wiklou.git] / tests / qunit / suites / resources / jquery / jquery.byteLimit.test.js
1 ( function ( $, mw ) {
2 var simpleSample, U_20AC, mbSample;
3
4 QUnit.module( 'jquery.byteLimit', QUnit.newMwEnvironment() );
5
6 // Simple sample (20 chars, 20 bytes)
7 simpleSample = '12345678901234567890';
8
9 // 3 bytes (euro-symbol)
10 U_20AC = '\u20AC';
11
12 // Multi-byte sample (22 chars, 26 bytes)
13 mbSample = '1234567890' + U_20AC + '1234567890' + U_20AC;
14
15 // Basic sendkey-implementation
16 function addChars( $input, charstr ) {
17 var c, len;
18
19 function x( $input, i ) {
20 // Add character to the value
21 return $input.val() + charstr.charAt( i );
22 }
23
24 for ( c = 0, len = charstr.length; c < len; c += 1 ) {
25 $input
26 .val( x( $input, c ) )
27 .trigger( 'change' );
28 }
29 }
30
31 /**
32 * Test factory for $.fn.byteLimit
33 *
34 * @param $input {jQuery} jQuery object in an input element
35 * @param hasLimit {Boolean} Wether a limit should apply at all
36 * @param limit {Number} Limit (if used) otherwise undefined
37 * The limit should be less than 20 (the sample data's length)
38 */
39 function byteLimitTest( options ) {
40 var opt = $.extend( {
41 description: '',
42 $input: null,
43 sample: '',
44 hasLimit: false,
45 expected: '',
46 limit: null
47 }, options );
48
49 QUnit.asyncTest( opt.description, opt.hasLimit ? 3 : 2, function ( assert ) {
50 setTimeout( function () {
51 var rawVal, fn, effectiveVal;
52
53 opt.$input.appendTo( '#qunit-fixture' );
54
55 // Simulate pressing keys for each of the sample characters
56 addChars( opt.$input, opt.sample );
57
58 rawVal = opt.$input.val();
59 fn = opt.$input.data( 'byteLimit.callback' );
60 effectiveVal = fn ? fn( rawVal ) : rawVal;
61
62 if ( opt.hasLimit ) {
63 assert.ltOrEq(
64 $.byteLength( effectiveVal ),
65 opt.limit,
66 'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
67 );
68 assert.equal(
69 $.byteLength( rawVal ),
70 $.byteLength( opt.expected ),
71 'Not preventing keypresses too early, length has reached the expected length'
72 );
73 assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
74
75 } else {
76 assert.equal(
77 $.byteLength( effectiveVal ),
78 $.byteLength( opt.expected ),
79 'Unlimited scenarios are not affected, expected length reached'
80 );
81 assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
82 }
83 QUnit.start();
84 }, 10 );
85 } );
86 }
87
88 byteLimitTest( {
89 description: 'Plain text input',
90 $input: $( '<input type="text"/>' ),
91 sample: simpleSample,
92 hasLimit: false,
93 expected: simpleSample
94 } );
95
96 byteLimitTest( {
97 description: 'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (bug 36310)',
98 $input: $( '<input type="text"/>' )
99 .byteLimit(),
100 sample: simpleSample,
101 hasLimit: false,
102 expected: simpleSample
103 } );
104
105 byteLimitTest( {
106 description: 'Limit using the maxlength attribute',
107 $input: $( '<input type="text"/>' )
108 .attr( 'maxlength', '10' )
109 .byteLimit(),
110 sample: simpleSample,
111 hasLimit: true,
112 limit: 10,
113 expected: '1234567890'
114 } );
115
116 byteLimitTest( {
117 description: 'Limit using a custom value',
118 $input: $( '<input type="text"/>' )
119 .byteLimit( 10 ),
120 sample: simpleSample,
121 hasLimit: true,
122 limit: 10,
123 expected: '1234567890'
124 } );
125
126 byteLimitTest( {
127 description: 'Limit using a custom value, overriding maxlength attribute',
128 $input: $( '<input type="text"/>' )
129 .attr( 'maxlength', '10' )
130 .byteLimit( 15 ),
131 sample: simpleSample,
132 hasLimit: true,
133 limit: 15,
134 expected: '123456789012345'
135 } );
136
137 byteLimitTest( {
138 description: 'Limit using a custom value (multibyte)',
139 $input: $( '<input type="text"/>' )
140 .byteLimit( 14 ),
141 sample: mbSample,
142 hasLimit: true,
143 limit: 14,
144 expected: '1234567890' + U_20AC + '1'
145 } );
146
147 byteLimitTest( {
148 description: 'Limit using a custom value (multibyte) overlapping a byte',
149 $input: $( '<input type="text"/>' )
150 .byteLimit( 12 ),
151 sample: mbSample,
152 hasLimit: true,
153 limit: 12,
154 expected: '1234567890' + '12'
155 } );
156
157 byteLimitTest( {
158 description: 'Pass the limit and a callback as input filter',
159 $input: $( '<input type="text"/>' )
160 .byteLimit( 6, function ( val ) {
161 // Invalid title
162 if ( val === '' ) {
163 return '';
164 }
165
166 // Return without namespace prefix
167 return new mw.Title( String( val ) ).getMain();
168 } ),
169 sample: 'User:Sample',
170 hasLimit: true,
171 limit: 6, // 'Sample' length
172 expected: 'User:Sample'
173 } );
174
175 byteLimitTest( {
176 description: 'Limit using the maxlength attribute and pass a callback as input filter',
177 $input: $( '<input type="text"/>' )
178 .attr( 'maxlength', '6' )
179 .byteLimit( function ( val ) {
180 // Invalid title
181 if ( val === '' ) {
182 return '';
183 }
184
185 // Return without namespace prefix
186 return new mw.Title( String( val ) ).getMain();
187 } ),
188 sample: 'User:Sample',
189 hasLimit: true,
190 limit: 6, // 'Sample' length
191 expected: 'User:Sample'
192 } );
193
194 QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) {
195 var $el, $elA, $elB;
196
197 $el = $( '<input type="text"/>' )
198 .attr( 'maxlength', '7' )
199 .appendTo( '#qunit-fixture' )
200 .byteLimit();
201
202 assert.strictEqual( $el.attr( 'maxlength' ), '7', 'maxlength attribute unchanged for simple limit' );
203
204 $el = $( '<input type="text"/>' )
205 .attr( 'maxlength', '7' )
206 .appendTo( '#qunit-fixture' )
207 .byteLimit( 12 );
208
209 assert.strictEqual( $el.attr( 'maxlength' ), '12', 'maxlength attribute updated for custom limit' );
210
211 $el = $( '<input type="text"/>' )
212 .attr( 'maxlength', '7' )
213 .appendTo( '#qunit-fixture' )
214 .byteLimit( 12, function ( val ) {
215 return val;
216 } );
217
218 assert.strictEqual( $el.attr( 'maxlength' ), undefined, 'maxlength attribute removed for limit with callback' );
219
220 $elA = $( '<input type="text"/>' )
221 .addClass( 'mw-test-byteLimit-foo' )
222 .attr( 'maxlength', '7' )
223 .appendTo( '#qunit-fixture' );
224
225 $elB = $( '<input type="text"/>' )
226 .addClass( 'mw-test-byteLimit-foo' )
227 .attr( 'maxlength', '12' )
228 .appendTo( '#qunit-fixture' );
229
230 $el = $( '.mw-test-byteLimit-foo' );
231
232 assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
233
234 $el.byteLimit();
235 } );
236
237 QUnit.test( 'Trim from insertion when limit exceeded', 2, function ( assert ) {
238 var $el;
239
240 // Use a new <input /> because the bug only occurs on the first time
241 // the limit it reached (bug 40850)
242 $el = $( '<input type="text"/>' )
243 .appendTo( '#qunit-fixture' )
244 .byteLimit( 3 )
245 .val( 'abc' ).trigger( 'change' )
246 .val( 'zabc' ).trigger( 'change' );
247
248 assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 0), not the end' );
249
250 $el = $( '<input type="text"/>' )
251 .appendTo( '#qunit-fixture' )
252 .byteLimit( 3 )
253 .val( 'abc' ).trigger( 'change' )
254 .val( 'azbc' ).trigger( 'change' );
255
256 assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 1), not the end' );
257 } );
258 }( jQuery, mediaWiki ) );