Merge "Use Linker::getInvalidTitleDescription() to display invalid title entries...
[lhc/web/wiklou.git] / tests / qunit / suites / resources / jquery / jquery.byteLimit.test.js
1 ( function ( $ ) {
2 var simpleSample, U_20AC, mbSample;
3
4 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 test( opt.description, function () {
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 expect(3);
70
71 QUnit.ltOrEq(
72 $.byteLength( newVal ),
73 opt.limit,
74 'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
75 );
76 equal(
77 $.byteLength( rawVal ),
78 $.byteLength( opt.expected ),
79 'Not preventing keypresses too early, length has reached the expected length'
80 );
81 equal( rawVal, opt.expected, 'New value matches the expected string' );
82
83 } else {
84 expect(2);
85 equal( newVal, opt.expected, 'New value matches the expected string' );
86 equal(
87 $.byteLength( newVal ),
88 $.byteLength( opt.expected ),
89 'Unlimited scenarios are not affected, expected length reached'
90 );
91 }
92 } );
93 }
94
95 test( '-- Initial check', function () {
96 expect(1);
97 ok( $.fn.byteLimit, 'jQuery.fn.byteLimit defined' );
98 } );
99
100 byteLimitTest({
101 description: 'Plain text input',
102 $input: $( '<input>' )
103 .attr( 'type', 'text' ),
104 sample: simpleSample,
105 hasLimit: false,
106 expected: simpleSample
107 });
108
109 byteLimitTest({
110 description: 'Plain text input. Calling byteLimit with no parameters and no maxLength property (bug 36310)',
111 $input: $( '<input>' )
112 .attr( 'type', 'text' )
113 .byteLimit(),
114 sample: simpleSample,
115 hasLimit: false,
116 expected: simpleSample
117 });
118
119 byteLimitTest({
120 description: 'Limit using the maxlength attribute',
121 $input: $( '<input>' )
122 .attr( 'type', 'text' )
123 .prop( 'maxLength', '10' )
124 .byteLimit(),
125 sample: simpleSample,
126 hasLimit: true,
127 limit: 10,
128 expected: '1234567890'
129 });
130
131 byteLimitTest({
132 description: 'Limit using a custom value',
133 $input: $( '<input>' )
134 .attr( 'type', 'text' )
135 .byteLimit( 10 ),
136 sample: simpleSample,
137 hasLimit: true,
138 limit: 10,
139 expected: '1234567890'
140 });
141
142 byteLimitTest({
143 description: 'Limit using a custom value, overriding maxlength attribute',
144 $input: $( '<input>' )
145 .attr( 'type', 'text' )
146 .prop( 'maxLength', '10' )
147 .byteLimit( 15 ),
148 sample: simpleSample,
149 hasLimit: true,
150 limit: 15,
151 expected: '123456789012345'
152 });
153
154 byteLimitTest({
155 description: 'Limit using a custom value (multibyte)',
156 $input: $( '<input>' )
157 .attr( 'type', 'text' )
158 .byteLimit( 14 ),
159 sample: mbSample,
160 hasLimit: true,
161 limit: 14,
162 expected: '1234567890' + U_20AC + '1'
163 });
164
165 byteLimitTest({
166 description: 'Limit using a custom value (multibyte) overlapping a byte',
167 $input: $( '<input>' )
168 .attr( 'type', 'text' )
169 .byteLimit( 12 ),
170 sample: mbSample,
171 hasLimit: true,
172 limit: 12,
173 expected: '1234567890' + '12'
174 });
175
176 byteLimitTest({
177 description: 'Pass the limit and a callback as input filter',
178 $input: $( '<input>' )
179 .attr( 'type', 'text' )
180 .byteLimit( 6, function ( val ) {
181 // Invalid title
182 if ( val === '' ) {
183 return '';
184 }
185
186 // Return without namespace prefix
187 return new mw.Title( String( val ) ).getMain();
188 } ),
189 sample: 'User:Sample',
190 hasLimit: true,
191 limit: 6, // 'Sample' length
192 expected: 'User:Sample'
193 });
194
195 byteLimitTest({
196 description: 'Limit using the maxlength attribute and pass a callback as input filter',
197 $input: $( '<input>' )
198 .attr( 'type', 'text' )
199 .prop( 'maxLength', '6' )
200 .byteLimit( function ( val ) {
201 // Invalid title
202 if ( val === '' ) {
203 return '';
204 }
205
206 // Return without namespace prefix
207 return new mw.Title( String( val ) ).getMain();
208 } ),
209 sample: 'User:Sample',
210 hasLimit: true,
211 limit: 6, // 'Sample' length
212 expected: 'User:Sample'
213 });
214
215 test( 'Confirm properties and attributes set', function () {
216 var $el, $elA, $elB;
217
218 expect(5);
219
220 $el = $( '<input>' )
221 .attr( 'type', 'text' )
222 .prop( 'maxLength', '7' )
223 .appendTo( '#qunit-fixture' )
224 .byteLimit();
225
226 strictEqual( $el.prop( 'maxLength' ), 7, 'Pre-set maxLength property unchanged' );
227
228 $el = $( '<input>' )
229 .attr( 'type', 'text' )
230 .prop( 'maxLength', '7' )
231 .appendTo( '#qunit-fixture' )
232 .byteLimit( 12 );
233
234 strictEqual( $el.prop( 'maxLength' ), 12, 'maxLength property updated if value was passed to $.fn.byteLimit' );
235
236 $elA = $( '<input>' )
237 .addClass( 'mw-test-byteLimit-foo' )
238 .attr( 'type', 'text' )
239 .prop( 'maxLength', '7' )
240 .appendTo( '#qunit-fixture' );
241
242 $elB = $( '<input>' )
243 .addClass( 'mw-test-byteLimit-foo' )
244 .attr( 'type', 'text' )
245 .prop( 'maxLength', '12' )
246 .appendTo( '#qunit-fixture' );
247
248 $el = $( '.mw-test-byteLimit-foo' );
249
250 strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
251
252 $el.byteLimit();
253
254 // Before bug 35294 was fixed, both $elA and $elB had maxLength set to 7,
255 // because $.fn.byteLimit sets:
256 // `limit = limitArg || this.prop( 'maxLength' ); this.prop( 'maxLength', limit )`
257 // and did so outside the each() loop.
258 strictEqual( $elA.prop( 'maxLength' ), 7, 'maxLength was not incorrectly set on #1 when calling byteLimit on multiple elements (bug 35294)' );
259 strictEqual( $elB.prop( 'maxLength' ), 12, 'maxLength was not incorrectly set on #2 when calling byteLimit on multiple elements (bug 35294)' );
260 });
261
262 }( jQuery ) );