23a93a78f87cf47a9b1212a8d2aa8784b50bcff9
[lhc/web/wiklou.git] / tests / qunit / suites / resources / jquery / jquery.byteLimit.test.js
1 ( function ( $ ) {
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 len, i, prevVal, code, event;
18 len = charstr.length;
19 for ( i = 0; i < len; i += 1 ) {
20 // Keep track of the previous value
21 prevVal = $input.val();
22
23 // Get the key code
24 code = charstr.charCodeAt( i );
25
26 // Trigger event and undo if prevented
27 event = new jQuery.Event( 'keypress', {
28 which: code,
29 keyCode: code,
30 charCode: code
31 } );
32 $input.trigger( event );
33 if ( !event.isDefaultPrevented() ) {
34 $input.val( prevVal + charstr.charAt( i ) );
35 }
36 }
37 }
38
39 /**
40 * Test factory for $.fn.byteLimit
41 *
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)
46 */
47 function byteLimitTest( options ) {
48 var opt = $.extend({
49 description: '',
50 $input: null,
51 sample: '',
52 hasLimit: false,
53 expected: '',
54 limit: null
55 }, options);
56
57 QUnit.test( opt.description, function ( assert ) {
58 var rawVal, fn, newVal;
59
60 opt.$input.appendTo( '#qunit-fixture' );
61
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;
67
68 if ( opt.hasLimit ) {
69 QUnit.expect(3);
70
71 assert.ltOrEq(
72 $.byteLength( newVal ),
73 opt.limit,
74 'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
75 );
76 assert.equal(
77 $.byteLength( rawVal ),
78 $.byteLength( opt.expected ),
79 'Not preventing keypresses too early, length has reached the expected length'
80 );
81 assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
82
83 } else {
84 QUnit.expect(2);
85 assert.equal( newVal, opt.expected, 'New value matches the expected string' );
86 assert.equal(
87 $.byteLength( newVal ),
88 $.byteLength( opt.expected ),
89 'Unlimited scenarios are not affected, expected length reached'
90 );
91 }
92 } );
93 }
94
95 byteLimitTest({
96 description: 'Plain text input',
97 $input: $( '<input>' )
98 .attr( 'type', 'text' ),
99 sample: simpleSample,
100 hasLimit: false,
101 expected: simpleSample
102 });
103
104 byteLimitTest({
105 description: 'Plain text input. Calling byteLimit with no parameters and no maxLength property (bug 36310)',
106 $input: $( '<input>' )
107 .attr( 'type', 'text' )
108 .byteLimit(),
109 sample: simpleSample,
110 hasLimit: false,
111 expected: simpleSample
112 });
113
114 byteLimitTest({
115 description: 'Limit using the maxlength attribute',
116 $input: $( '<input>' )
117 .attr( 'type', 'text' )
118 .prop( 'maxLength', '10' )
119 .byteLimit(),
120 sample: simpleSample,
121 hasLimit: true,
122 limit: 10,
123 expected: '1234567890'
124 });
125
126 byteLimitTest({
127 description: 'Limit using a custom value',
128 $input: $( '<input>' )
129 .attr( 'type', 'text' )
130 .byteLimit( 10 ),
131 sample: simpleSample,
132 hasLimit: true,
133 limit: 10,
134 expected: '1234567890'
135 });
136
137 byteLimitTest({
138 description: 'Limit using a custom value, overriding maxlength attribute',
139 $input: $( '<input>' )
140 .attr( 'type', 'text' )
141 .prop( 'maxLength', '10' )
142 .byteLimit( 15 ),
143 sample: simpleSample,
144 hasLimit: true,
145 limit: 15,
146 expected: '123456789012345'
147 });
148
149 byteLimitTest({
150 description: 'Limit using a custom value (multibyte)',
151 $input: $( '<input>' )
152 .attr( 'type', 'text' )
153 .byteLimit( 14 ),
154 sample: mbSample,
155 hasLimit: true,
156 limit: 14,
157 expected: '1234567890' + U_20AC + '1'
158 });
159
160 byteLimitTest({
161 description: 'Limit using a custom value (multibyte) overlapping a byte',
162 $input: $( '<input>' )
163 .attr( 'type', 'text' )
164 .byteLimit( 12 ),
165 sample: mbSample,
166 hasLimit: true,
167 limit: 12,
168 expected: '1234567890' + '12'
169 });
170
171 byteLimitTest({
172 description: 'Pass the limit and a callback as input filter',
173 $input: $( '<input>' )
174 .attr( 'type', 'text' )
175 .byteLimit( 6, function ( val ) {
176 // Invalid title
177 if ( val === '' ) {
178 return '';
179 }
180
181 // Return without namespace prefix
182 return new mw.Title( String( val ) ).getMain();
183 } ),
184 sample: 'User:Sample',
185 hasLimit: true,
186 limit: 6, // 'Sample' length
187 expected: 'User:Sample'
188 });
189
190 byteLimitTest({
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 ) {
196 // Invalid title
197 if ( val === '' ) {
198 return '';
199 }
200
201 // Return without namespace prefix
202 return new mw.Title( String( val ) ).getMain();
203 } ),
204 sample: 'User:Sample',
205 hasLimit: true,
206 limit: 6, // 'Sample' length
207 expected: 'User:Sample'
208 });
209
210 QUnit.test( 'Confirm properties and attributes set', 5, function ( assert ) {
211 var $el, $elA, $elB;
212
213 $el = $( '<input>' )
214 .attr( 'type', 'text' )
215 .prop( 'maxLength', '7' )
216 .appendTo( '#qunit-fixture' )
217 .byteLimit();
218
219 assert.strictEqual( $el.prop( 'maxLength' ), 7, 'Pre-set maxLength property unchanged' );
220
221 $el = $( '<input>' )
222 .attr( 'type', 'text' )
223 .prop( 'maxLength', '7' )
224 .appendTo( '#qunit-fixture' )
225 .byteLimit( 12 );
226
227 assert.strictEqual( $el.prop( 'maxLength' ), 12, 'maxLength property updated if value was passed to $.fn.byteLimit' );
228
229 $elA = $( '<input>' )
230 .addClass( 'mw-test-byteLimit-foo' )
231 .attr( 'type', 'text' )
232 .prop( 'maxLength', '7' )
233 .appendTo( '#qunit-fixture' );
234
235 $elB = $( '<input>' )
236 .addClass( 'mw-test-byteLimit-foo' )
237 .attr( 'type', 'text' )
238 .prop( 'maxLength', '12' )
239 .appendTo( '#qunit-fixture' );
240
241 $el = $( '.mw-test-byteLimit-foo' );
242
243 assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
244
245 $el.byteLimit();
246
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)' );
253 });
254
255 }( jQuery ) );