Merge "misc style issues"
[lhc/web/wiklou.git] / tests / qunit / suites / resources / jquery / jquery.tablesorter.test.js
1 ( function ( $, mw ) {
2 /*jshint onevar: false */
3
4 var config = {
5 wgMonthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
6 wgMonthNamesShort: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
7 wgDefaultDateFormat: 'dmy',
8 wgContentLanguage: 'en'
9 };
10
11 QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment({ config: config }) );
12
13 /**
14 * Create an HTML table from an array of row arrays containing text strings.
15 * First row will be header row. No fancy rowspan/colspan stuff.
16 *
17 * @param {String[]} header
18 * @param {String[][]} data
19 * @return jQuery
20 */
21 function tableCreate( header, data ) {
22 var i,
23 $table = $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
24 $thead = $table.find( 'thead' ),
25 $tbody = $table.find( 'tbody' ),
26 $tr = $( '<tr>' );
27
28 $.each( header, function ( i, str ) {
29 var $th = $( '<th>' );
30 $th.text( str ).appendTo( $tr );
31 });
32 $tr.appendTo( $thead );
33
34 for ( i = 0; i < data.length; i++ ) {
35 /*jshint loopfunc: true */
36 $tr = $( '<tr>' );
37 $.each( data[i], function ( j, str ) {
38 var $td = $( '<td>' );
39 $td.text( str ).appendTo( $tr );
40 });
41 $tr.appendTo( $tbody );
42 }
43 return $table;
44 }
45
46 /**
47 * Extract text from table.
48 *
49 * @param {jQuery} $table
50 * @return String[][]
51 */
52 function tableExtract( $table ) {
53 var data = [];
54
55 $table.find( 'tbody' ).find( 'tr' ).each( function( i, tr ) {
56 var row = [];
57 $( tr ).find( 'td,th' ).each( function( i, td ) {
58 row.push( $( td ).text() );
59 });
60 data.push( row );
61 });
62 return data;
63 }
64
65 /**
66 * Run a table test by building a table with the given data,
67 * running some callback on it, then checking the results.
68 *
69 * @param {String} msg text to pass on to qunit for the comparison
70 * @param {String[]} header cols to make the table
71 * @param {String[][]} data rows/cols to make the table
72 * @param {String[][]} expected rows/cols to compare against at end
73 * @param {function($table)} callback something to do with the table before we compare
74 */
75 function tableTest( msg, header, data, expected, callback ) {
76 QUnit.test( msg, 1, function ( assert ) {
77 var $table = tableCreate( header, data );
78
79 // Give caller a chance to set up sorting and manipulate the table.
80 callback( $table );
81
82 // Table sorting is done synchronously; if it ever needs to change back
83 // to asynchronous, we'll need a timeout or a callback here.
84 var extracted = tableExtract( $table );
85 assert.deepEqual( extracted, expected, msg );
86 });
87 }
88
89 function reversed(arr) {
90 // Clone array
91 var arr2 = arr.slice(0);
92
93 arr2.reverse();
94
95 return arr2;
96 }
97
98 // Sample data set using planets named and their radius
99 var header = [ 'Planet' , 'Radius (km)'],
100 mercury = [ 'Mercury', '2439.7' ],
101 venus = [ 'Venus' , '6051.8' ],
102 earth = [ 'Earth' , '6371.0' ],
103 mars = [ 'Mars' , '3390.0' ],
104 jupiter = [ 'Jupiter', '69911' ],
105 saturn = [ 'Saturn' , '58232' ];
106
107 // Initial data set
108 var planets = [mercury, venus, earth, mars, jupiter, saturn];
109 var ascendingName = [earth, jupiter, mars, mercury, saturn, venus];
110 var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter];
111
112 tableTest(
113 'Basic planet table: sorting initially - ascending by name',
114 header,
115 planets,
116 ascendingName,
117 function ( $table ) {
118 $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
119 }
120 );
121 tableTest(
122 'Basic planet table: sorting initially - descending by radius',
123 header,
124 planets,
125 reversed(ascendingRadius),
126 function ( $table ) {
127 $table.tablesorter( { sortList: [ { 1: 'desc' } ] } );
128 }
129 );
130 tableTest(
131 'Basic planet table: ascending by name',
132 header,
133 planets,
134 ascendingName,
135 function ( $table ) {
136 $table.tablesorter();
137 $table.find( '.headerSort:eq(0)' ).click();
138 }
139 );
140 tableTest(
141 'Basic planet table: ascending by name a second time',
142 header,
143 planets,
144 ascendingName,
145 function ( $table ) {
146 $table.tablesorter();
147 $table.find( '.headerSort:eq(0)' ).click();
148 }
149 );
150 tableTest(
151 'Basic planet table: descending by name',
152 header,
153 planets,
154 reversed(ascendingName),
155 function ( $table ) {
156 $table.tablesorter();
157 $table.find( '.headerSort:eq(0)' ).click().click();
158 }
159 );
160 tableTest(
161 'Basic planet table: ascending radius',
162 header,
163 planets,
164 ascendingRadius,
165 function ( $table ) {
166 $table.tablesorter();
167 $table.find( '.headerSort:eq(1)' ).click();
168 }
169 );
170 tableTest(
171 'Basic planet table: descending radius',
172 header,
173 planets,
174 reversed(ascendingRadius),
175 function ( $table ) {
176 $table.tablesorter();
177 $table.find( '.headerSort:eq(1)' ).click().click();
178 }
179 );
180
181 // Sample data set to test multiple column sorting
182 header = [ 'column1' , 'column2'];
183 var
184 a1 = [ 'A', '1' ],
185 a2 = [ 'A', '2' ],
186 a3 = [ 'A', '3' ],
187 b1 = [ 'B', '1' ],
188 b2 = [ 'B', '2' ],
189 b3 = [ 'B', '3' ];
190 var initial = [a2, b3, a1, a3, b2, b1];
191 var asc = [a1, a2, a3, b1, b2, b3];
192 var descasc = [b1, b2, b3, a1, a2, a3];
193
194 tableTest(
195 'Sorting multiple columns by passing sort list',
196 header,
197 initial,
198 asc,
199 function ( $table ) {
200 $table.tablesorter(
201 { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
202 );
203 }
204 );
205 tableTest(
206 'Sorting multiple columns by programmatically triggering sort()',
207 header,
208 initial,
209 descasc,
210 function ( $table ) {
211 $table.tablesorter();
212 $table.data( 'tablesorter' ).sort(
213 [ { 0: 'desc' }, { 1: 'asc' } ]
214 );
215 }
216 );
217 tableTest(
218 'Reset to initial sorting by triggering sort() without any parameters',
219 header,
220 initial,
221 asc,
222 function ( $table ) {
223 $table.tablesorter(
224 { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
225 );
226 $table.data( 'tablesorter' ).sort(
227 [ { 0: 'desc' }, { 1: 'asc' } ]
228 );
229 $table.data( 'tablesorter' ).sort();
230 }
231 );
232 QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) {
233 var $table = tableCreate( header, initial );
234 $table.tablesorter(
235 { sortList: [ { 0: 'desc' }, { 1: 'asc' } ] }
236 );
237 $table.data( 'tablesorter' ).sort( [] );
238
239 assert.equal(
240 $table.find( 'th.headerSortUp' ).length + $table.find( 'th.headerSortDown' ).length,
241 0,
242 'No sort specific sort classes addign to header cells'
243 );
244
245 assert.equal(
246 $table.find( 'th' ).first().attr( 'title' ),
247 mw.msg( 'sort-ascending' ),
248 'First header cell has default title'
249 );
250
251 assert.equal(
252 $table.find( 'th' ).first().attr( 'title' ),
253 $table.find( 'th' ).last().attr( 'title' ),
254 'Both header cells\' titles match'
255 );
256 } );
257
258 // Sorting with colspans
259 header = [ 'column1a' , 'column1b', 'column1c', 'column2' ];
260 var
261 aaa1 = [ 'A', 'A', 'A', '1' ],
262 aab5 = [ 'A', 'A', 'B', '5' ],
263 abc3 = [ 'A', 'B', 'C', '3' ],
264 bbc2 = [ 'B', 'B', 'C', '2' ],
265 caa4 = [ 'C', 'A', 'A', '4' ];
266 // initial is already declared above
267 initial = [ aab5, aaa1, abc3, bbc2, caa4 ];
268 tableTest( 'Sorting with colspanned headers: spanned column',
269 header,
270 initial,
271 [ aaa1, aab5, abc3, bbc2, caa4 ],
272 function ( $table ) {
273 // Make colspanned header for test
274 $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove();
275 $table.find( 'tr:eq(0) th:eq(0)' ).prop( 'colspan', '3' );
276
277 $table.tablesorter();
278 $table.find( '.headerSort:eq(0)' ).click();
279 }
280 );
281 tableTest( 'Sorting with colspanned headers: subsequent column',
282 header,
283 initial,
284 [ aaa1, bbc2, abc3, caa4, aab5 ],
285 function ( $table ) {
286 // Make colspanned header for test
287 $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove();
288 $table.find( 'tr:eq(0) th:eq(0)' ).prop( 'colspan', '3' );
289
290 $table.tablesorter();
291 $table.find( '.headerSort:eq(1)' ).click();
292 }
293 );
294
295 // Regression tests!
296 tableTest(
297 'Bug 28775: German-style (dmy) short numeric dates',
298 ['Date'],
299 [ // German-style dates are day-month-year
300 ['11.11.2011'],
301 ['01.11.2011'],
302 ['02.10.2011'],
303 ['03.08.2011'],
304 ['09.11.2011']
305 ],
306 [ // Sorted by ascending date
307 ['03.08.2011'],
308 ['02.10.2011'],
309 ['01.11.2011'],
310 ['09.11.2011'],
311 ['11.11.2011']
312 ],
313 function ( $table ) {
314 mw.config.set( 'wgDefaultDateFormat', 'dmy' );
315 mw.config.set( 'wgContentLanguage', 'de' );
316
317 $table.tablesorter();
318 $table.find( '.headerSort:eq(0)' ).click();
319 }
320 );
321
322 tableTest(
323 'Bug 28775: American-style (mdy) short numeric dates',
324 ['Date'],
325 [ // American-style dates are month-day-year
326 ['11.11.2011'],
327 ['01.11.2011'],
328 ['02.10.2011'],
329 ['03.08.2011'],
330 ['09.11.2011']
331 ],
332 [ // Sorted by ascending date
333 ['01.11.2011'],
334 ['02.10.2011'],
335 ['03.08.2011'],
336 ['09.11.2011'],
337 ['11.11.2011']
338 ],
339 function ( $table ) {
340 mw.config.set( 'wgDefaultDateFormat', 'mdy' );
341
342 $table.tablesorter();
343 $table.find( '.headerSort:eq(0)' ).click();
344 }
345 );
346
347 var ipv4 = [
348 // Some randomly generated fake IPs
349 ['45.238.27.109'],
350 ['44.172.9.22'],
351 ['247.240.82.209'],
352 ['204.204.132.158'],
353 ['170.38.91.162'],
354 ['197.219.164.9'],
355 ['45.68.154.72'],
356 ['182.195.149.80']
357 ];
358 var ipv4Sorted = [
359 // Sort order should go octet by octet
360 ['44.172.9.22'],
361 ['45.68.154.72'],
362 ['45.238.27.109'],
363 ['170.38.91.162'],
364 ['182.195.149.80'],
365 ['197.219.164.9'],
366 ['204.204.132.158'],
367 ['247.240.82.209']
368 ];
369
370 tableTest(
371 'Bug 17141: IPv4 address sorting',
372 ['IP'],
373 ipv4,
374 ipv4Sorted,
375 function ( $table ) {
376 $table.tablesorter();
377 $table.find( '.headerSort:eq(0)' ).click();
378 }
379 );
380 tableTest(
381 'Bug 17141: IPv4 address sorting (reverse)',
382 ['IP'],
383 ipv4,
384 reversed(ipv4Sorted),
385 function ( $table ) {
386 $table.tablesorter();
387 $table.find( '.headerSort:eq(0)' ).click().click();
388 }
389 );
390
391 var umlautWords = [
392 // Some words with Umlauts
393 ['Günther'],
394 ['Peter'],
395 ['Björn'],
396 ['Bjorn'],
397 ['Apfel'],
398 ['Äpfel'],
399 ['Strasse'],
400 ['Sträßschen']
401 ];
402
403 var umlautWordsSorted = [
404 // Some words with Umlauts
405 ['Äpfel'],
406 ['Apfel'],
407 ['Björn'],
408 ['Bjorn'],
409 ['Günther'],
410 ['Peter'],
411 ['Sträßschen'],
412 ['Strasse']
413 ];
414
415 tableTest(
416 'Accented Characters with custom collation',
417 ['Name'],
418 umlautWords,
419 umlautWordsSorted,
420 function ( $table ) {
421 mw.config.set( 'tableSorterCollation', {
422 'ä': 'ae',
423 'ö': 'oe',
424 'ß': 'ss',
425 'ü':'ue'
426 } );
427
428 $table.tablesorter();
429 $table.find( '.headerSort:eq(0)' ).click();
430 }
431 );
432
433 QUnit.test( 'Rowspan not exploded on init', 1, function ( assert ) {
434 var $table = tableCreate( header, planets );
435
436 // Modify the table to have a multiple-row-spanning cell:
437 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
438 $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
439 // - Set rowspan for 2nd cell of 3rd row to 3.
440 // This covers the removed cell in the 4th and 5th row.
441 $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
442
443 $table.tablesorter();
444
445 assert.equal(
446 $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan' ),
447 3,
448 'Rowspan not exploded'
449 );
450 });
451
452 var planetsRowspan = [ [ 'Earth', '6051.8' ], jupiter, [ 'Mars', '6051.8' ], mercury, saturn, venus ];
453 var planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
454
455 tableTest(
456 'Basic planet table: same value for multiple rows via rowspan',
457 header,
458 planets,
459 planetsRowspan,
460 function ( $table ) {
461 // Modify the table to have a multiple-row-spanning cell:
462 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
463 $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
464 // - Set rowspan for 2nd cell of 3rd row to 3.
465 // This covers the removed cell in the 4th and 5th row.
466 $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
467
468 $table.tablesorter();
469 $table.find( '.headerSort:eq(0)' ).click();
470 }
471 );
472 tableTest(
473 'Basic planet table: same value for multiple rows via rowspan (sorting initially)',
474 header,
475 planets,
476 planetsRowspan,
477 function ( $table ) {
478 // Modify the table to have a multiple-row-spanning cell:
479 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
480 $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
481 // - Set rowspan for 2nd cell of 3rd row to 3.
482 // This covers the removed cell in the 4th and 5th row.
483 $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
484
485 $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
486 }
487 );
488 tableTest(
489 'Basic planet table: Same value for multiple rows via rowspan II',
490 header,
491 planets,
492 planetsRowspanII,
493 function ( $table ) {
494 // Modify the table to have a multiple-row-spanning cell:
495 // - Remove 1st cell of 4th row, and, 1st cell or 5th row.
496 $table.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove();
497 // - Set rowspan for 1st cell of 3rd row to 3.
498 // This covers the removed cell in the 4th and 5th row.
499 $table.find( 'tr:eq(2) td:eq(0)' ).prop( 'rowspan', '3' );
500
501 $table.tablesorter();
502 $table.find( '.headerSort:eq(0)' ).click();
503 }
504 );
505
506 var complexMDYDates = [
507 // Some words with Umlauts
508 ['January, 19 2010'],
509 ['April 21 1991'],
510 ['04 22 1991'],
511 ['5.12.1990'],
512 ['December 12 \'10']
513 ];
514
515 var complexMDYSorted = [
516 ['5.12.1990'],
517 ['April 21 1991'],
518 ['04 22 1991'],
519 ['January, 19 2010'],
520 ['December 12 \'10']
521 ];
522
523 tableTest(
524 'Complex date parsing I',
525 ['date'],
526 complexMDYDates,
527 complexMDYSorted,
528 function ( $table ) {
529 mw.config.set( 'wgDefaultDateFormat', 'mdy' );
530
531 $table.tablesorter();
532 $table.find( '.headerSort:eq(0)' ).click();
533 }
534 );
535
536 var currencyUnsorted = [
537 ['1.02 $'],
538 ['$ 3.00'],
539 ['€ 2,99'],
540 ['$ 1.00'],
541 ['$3.50'],
542 ['$ 1.50'],
543 ['€ 0.99']
544 ];
545
546 var currencySorted = [
547 ['€ 0.99'],
548 ['$ 1.00'],
549 ['1.02 $'],
550 ['$ 1.50'],
551 ['$ 3.00'],
552 ['$3.50'],
553 // Comma's sort after dots
554 // Not intentional but test to detect changes
555 ['€ 2,99']
556 ];
557
558 tableTest(
559 'Currency parsing I',
560 ['currency'],
561 currencyUnsorted,
562 currencySorted,
563 function ( $table ) {
564 $table.tablesorter();
565 $table.find( '.headerSort:eq(0)' ).click();
566 }
567 );
568
569 var ascendingNameLegacy = ascendingName.slice(0);
570 ascendingNameLegacy[4] = ascendingNameLegacy[5];
571 ascendingNameLegacy.pop();
572
573 tableTest(
574 'Legacy compat with .sortbottom',
575 header,
576 planets,
577 ascendingNameLegacy,
578 function( $table ) {
579 $table.find( 'tr:last' ).addClass( 'sortbottom' );
580 $table.tablesorter();
581 $table.find( '.headerSort:eq(0)' ).click();
582 }
583 );
584
585 QUnit.test( 'Test detection routine', function ( assert ) {
586 var $table;
587 $table = $(
588 '<table class="sortable">' +
589 '<caption>CAPTION</caption>' +
590 '<tr><th>THEAD</th></tr>' +
591 '<tr><td>1</td></tr>' +
592 '<tr class="sortbottom"><td>text</td></tr>' +
593 '</table>'
594 );
595 $table.tablesorter();
596 $table.find( '.headerSort:eq(0)' ).click();
597
598 assert.equal(
599 $table.data( 'tablesorter' ).config.parsers[0].id,
600 'number',
601 'Correctly detected column content skipping sortbottom'
602 );
603 } );
604
605 /** FIXME: the diff output is not very readeable. */
606 QUnit.test( 'bug 32047 - caption must be before thead', function ( assert ) {
607 var $table;
608 $table = $(
609 '<table class="sortable">' +
610 '<caption>CAPTION</caption>' +
611 '<tr><th>THEAD</th></tr>' +
612 '<tr><td>A</td></tr>' +
613 '<tr><td>B</td></tr>' +
614 '<tr class="sortbottom"><td>TFOOT</td></tr>' +
615 '</table>'
616 );
617 $table.tablesorter();
618
619 assert.equal(
620 $table.children( ).get( 0 ).nodeName,
621 'CAPTION',
622 'First element after <thead> must be <caption> (bug 32047)'
623 );
624 });
625
626 QUnit.test( 'data-sort-value attribute, when available, should override sorting position', function ( assert ) {
627 var $table, data;
628
629 // Example 1: All cells except one cell without data-sort-value,
630 // which should be sorted at it's text content value.
631 $table = $(
632 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
633 '<tbody>' +
634 '<tr><td>Cheetah</td></tr>' +
635 '<tr><td data-sort-value="Apple">Bird</td></tr>' +
636 '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
637 '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
638 '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
639 '</tbody></table>'
640 );
641 $table.tablesorter().find( '.headerSort:eq(0)' ).click();
642
643 data = [];
644 $table.find( 'tbody > tr' ).each( function( i, tr ) {
645 $( tr ).find( 'td' ).each( function( i, td ) {
646 data.push( {
647 data: $( td ).data( 'sortValue' ),
648 text: $( td ).text()
649 } );
650 });
651 });
652
653 assert.deepEqual( data, [
654 {
655 data: 'Apple',
656 text: 'Bird'
657 }, {
658 data: 'Bananna',
659 text: 'Ferret'
660 }, {
661 data: undefined,
662 text: 'Cheetah'
663 }, {
664 data: 'Cherry',
665 text: 'Dolphin'
666 }, {
667 data: 'Drupe',
668 text: 'Elephant'
669 }
670 ], 'Order matches expected order (based on data-sort-value attribute values)' );
671
672 // Example 2
673 $table = $(
674 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
675 '<tbody>' +
676 '<tr><td>D</td></tr>' +
677 '<tr><td data-sort-value="E">A</td></tr>' +
678 '<tr><td>B</td></tr>' +
679 '<tr><td>G</td></tr>' +
680 '<tr><td data-sort-value="F">C</td></tr>' +
681 '</tbody></table>'
682 );
683 $table.tablesorter().find( '.headerSort:eq(0)' ).click();
684
685 data = [];
686 $table.find( 'tbody > tr' ).each( function ( i, tr ) {
687 $( tr ).find( 'td' ).each( function ( i, td ) {
688 data.push( {
689 data: $( td ).data( 'sortValue' ),
690 text: $( td ).text()
691 } );
692 });
693 });
694
695 assert.deepEqual( data, [
696 {
697 data: undefined,
698 text: 'B'
699 }, {
700 data: undefined,
701 text: 'D'
702 }, {
703 data: 'E',
704 text: 'A'
705 }, {
706 data: 'F',
707 text: 'C'
708 }, {
709 data: undefined,
710 text: 'G'
711 }
712 ], 'Order matches expected order (based on data-sort-value attribute values)' );
713
714 // Example 3: Test that live changes are used from data-sort-value,
715 // even if they change after the tablesorter is constructed (bug 38152).
716 $table = $(
717 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
718 '<tbody>' +
719 '<tr><td>D</td></tr>' +
720 '<tr><td data-sort-value="1">A</td></tr>' +
721 '<tr><td>B</td></tr>' +
722 '<tr><td data-sort-value="2">G</td></tr>' +
723 '<tr><td>C</td></tr>' +
724 '</tbody></table>'
725 );
726 // initialize table sorter and sort once
727 $table
728 .tablesorter()
729 .find( '.headerSort:eq(0)' ).click();
730
731 // Change the sortValue data properties (bug 38152)
732 // - change data
733 $table.find( 'td:contains(A)' ).data( 'sortValue', 3 );
734 // - add data
735 $table.find( 'td:contains(B)' ).data( 'sortValue', 1 );
736 // - remove data, bring back attribute: 2
737 $table.find( 'td:contains(G)' ).removeData( 'sortValue' );
738
739 // Now sort again (twice, so it is back at Ascending)
740 $table.find( '.headerSort:eq(0)' ).click();
741 $table.find( '.headerSort:eq(0)' ).click();
742
743 data = [];
744 $table.find( 'tbody > tr' ).each( function( i, tr ) {
745 $( tr ).find( 'td' ).each( function( i, td ) {
746 data.push( {
747 data: $( td ).data( 'sortValue' ),
748 text: $( td ).text()
749 } );
750 });
751 });
752
753 assert.deepEqual( data, [
754 {
755 data: 1,
756 text: 'B'
757 }, {
758 data: 2,
759 text: 'G'
760 }, {
761 data: 3,
762 text: 'A'
763 }, {
764 data: undefined,
765 text: 'C'
766 }, {
767 data: undefined,
768 text: 'D'
769 }
770 ], 'Order matches expected order, using the current sortValue in $.data()' );
771
772 });
773
774 var numbers = [
775 [ '12' ],
776 [ '7' ],
777 [ '13,000'],
778 [ '9' ],
779 [ '14' ],
780 [ '8.0' ]
781 ];
782 var numbersAsc = [
783 [ '7' ],
784 [ '8.0' ],
785 [ '9' ],
786 [ '12' ],
787 [ '14' ],
788 [ '13,000']
789 ];
790
791 tableTest( 'bug 8115: sort numbers with commas (ascending)',
792 ['Numbers'], numbers, numbersAsc,
793 function( $table ) {
794 $table.tablesorter();
795 $table.find( '.headerSort:eq(0)' ).click();
796 }
797 );
798
799 tableTest( 'bug 8115: sort numbers with commas (descending)',
800 ['Numbers'], numbers, reversed(numbersAsc),
801 function( $table ) {
802 $table.tablesorter();
803 $table.find( '.headerSort:eq(0)' ).click().click();
804 }
805 );
806 // TODO add numbers sorting tests for bug 8115 with a different language
807
808 QUnit.test( 'bug 32888 - Tables inside a tableheader cell', 2, function ( assert ) {
809 var $table;
810 $table = $(
811 '<table class="sortable" id="mw-bug-32888">' +
812 '<tr><th>header<table id="mw-bug-32888-2">'+
813 '<tr><th>1</th><th>2</th></tr>' +
814 '</table></th></tr>' +
815 '<tr><td>A</td></tr>' +
816 '<tr><td>B</td></tr>' +
817 '</table>'
818 );
819 $table.tablesorter();
820
821 assert.equal(
822 $table.find('> thead:eq(0) > tr > th.headerSort').length,
823 1,
824 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
825 );
826 assert.equal(
827 $( '#mw-bug-32888-2' ).find('th.headerSort').length,
828 0,
829 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'
830 );
831 });
832
833
834 var correctDateSorting1 = [
835 ['01 January 2010'],
836 ['05 February 2010'],
837 ['16 January 2010']
838 ];
839
840 var correctDateSortingSorted1 = [
841 ['01 January 2010'],
842 ['16 January 2010'],
843 ['05 February 2010']
844 ];
845
846 tableTest(
847 'Correct date sorting I',
848 ['date'],
849 correctDateSorting1,
850 correctDateSortingSorted1,
851 function ( $table ) {
852 mw.config.set( 'wgDefaultDateFormat', 'mdy' );
853
854 $table.tablesorter();
855 $table.find( '.headerSort:eq(0)' ).click();
856 }
857 );
858
859 var correctDateSorting2 = [
860 ['January 01 2010'],
861 ['February 05 2010'],
862 ['January 16 2010']
863 ];
864
865 var correctDateSortingSorted2 = [
866 ['January 01 2010'],
867 ['January 16 2010'],
868 ['February 05 2010']
869 ];
870
871 tableTest(
872 'Correct date sorting II',
873 ['date'],
874 correctDateSorting2,
875 correctDateSortingSorted2,
876 function ( $table ) {
877 mw.config.set( 'wgDefaultDateFormat', 'dmy' );
878
879 $table.tablesorter();
880 $table.find( '.headerSort:eq(0)' ).click();
881 }
882 );
883
884 QUnit.test( 'Sorting images using alt text', function ( assert ) {
885 var $table = $(
886 '<table class="sortable">' +
887 '<tr><th>THEAD</th></tr>' +
888 '<tr><td><img alt="2"/></td></tr>' +
889 '<tr><td>1</td></tr>' +
890 '</table>'
891 );
892 $table.tablesorter().find( '.headerSort:eq(0)' ).click();
893
894 assert.equal(
895 $table.find( 'td' ).first().text(),
896 '1',
897 'Applied correct sorting order'
898 );
899 } );
900
901 QUnit.test( 'Sorting images using alt text (complex)', function ( assert ) {
902 var $table = $(
903 '<table class="sortable">' +
904 '<tr><th>THEAD</th></tr>' +
905 '<tr><td><img alt="D" />A</td></tr>' +
906 '<tr><td>CC</td></tr>' +
907 '<tr><td><a><img alt="A" /></a>F</tr>' +
908 '<tr><td><img alt="A" /><strong>E</strong></tr>' +
909 '<tr><td><strong><img alt="A" />D</strong></tr>' +
910 '<tr><td><img alt="A" />C</tr>' +
911 '</table>'
912 );
913 $table.tablesorter().find( '.headerSort:eq(0)' ).click();
914
915 assert.equal(
916 $table.find( 'td' ).text(),
917 'CDEFCCA',
918 'Applied correct sorting order'
919 );
920 } );
921
922 QUnit.test( 'Sorting images using alt text (with format autodetection)', function ( assert ) {
923 var $table = $(
924 '<table class="sortable">' +
925 '<tr><th>THEAD</th></tr>' +
926 '<tr><td><img alt="1" />7</td></tr>' +
927 '<tr><td>1<img alt="6" /></td></tr>' +
928 '<tr><td>5</td></tr>' +
929 '<tr><td>4</td></tr>' +
930 '</table>'
931 );
932 $table.tablesorter().find( '.headerSort:eq(0)' ).click();
933
934 assert.equal(
935 $table.find( 'td' ).text(),
936 '4517',
937 'Applied correct sorting order'
938 );
939 } );
940
941 }( jQuery, mediaWiki ) );