a76af5e9847c622ac829a7aba104229e88f7d949
4 wgMonthNames
: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
5 wgMonthNamesShort
: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
6 wgDefaultDateFormat
: 'dmy',
7 wgContentLanguage
: 'en'
10 module( 'jquery.tablesorter', QUnit
.newMwEnvironment( config
) );
12 test( '-- Initial check', function() {
14 ok( $.tablesorter
, '$.tablesorter defined' );
18 * Create an HTML table from an array of row arrays containing text strings.
19 * First row will be header row. No fancy rowspan/colspan stuff.
21 * @param {String[]} header
22 * @param {String[][]} data
25 var tableCreate = function( header
, data
) {
26 var $table
= $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
27 $thead
= $table
.find( 'thead' ),
28 $tbody
= $table
.find( 'tbody' ),
31 $.each( header
, function( i
, str
) {
32 var $th
= $( '<th>' );
33 $th
.text( str
).appendTo( $tr
);
35 $tr
.appendTo( $thead
);
37 for (var i
= 0; i
< data
.length
; i
++) {
39 $.each( data
[i
], function( j
, str
) {
40 var $td
= $( '<td>' );
41 $td
.text( str
).appendTo( $tr
);
43 $tr
.appendTo( $tbody
);
49 * Extract text from table.
51 * @param {jQuery} $table
54 var tableExtract = function( $table
) {
57 $table
.find( 'tbody' ).find( 'tr' ).each( function( i
, tr
) {
59 $( tr
).find( 'td,th' ).each( function( i
, td
) {
60 row
.push( $( td
).text() );
68 * Run a table test by building a table with the given data,
69 * running some callback on it, then checking the results.
71 * @param {String} msg text to pass on to qunit for the comparison
72 * @param {String[]} header cols to make the table
73 * @param {String[][]} data rows/cols to make the table
74 * @param {String[][]} expected rows/cols to compare against at end
75 * @param {function($table)} callback something to do with the table before we compare
77 var tableTest = function( msg
, header
, data
, expected
, callback
) {
78 test( msg
, function() {
81 var $table
= tableCreate( header
, data
);
83 // Give caller a chance to set up sorting and manipulate the table.
86 // Table sorting is done synchronously; if it ever needs to change back
87 // to asynchronous, we'll need a timeout or a callback here.
88 var extracted
= tableExtract( $table
);
89 deepEqual( extracted
, expected
, msg
);
93 var reversed = function(arr
) {
94 var arr2
= arr
.slice(0);
99 // Sample data set using planets named and their radius
100 var header
= [ 'Planet' , 'Radius (km)'],
101 mercury
= [ 'Mercury', '2439.7' ],
102 venus
= [ 'Venus' , '6051.8' ],
103 earth
= [ 'Earth' , '6371.0' ],
104 mars
= [ 'Mars' , '3390.0' ],
105 jupiter
= [ 'Jupiter', '69911' ],
106 saturn
= [ 'Saturn' , '58232' ];
109 var planets
= [mercury
, venus
, earth
, mars
, jupiter
, saturn
];
110 var ascendingName
= [earth
, jupiter
, mars
, mercury
, saturn
, venus
];
111 var ascendingRadius
= [mercury
, mars
, venus
, earth
, saturn
, jupiter
];
114 'Basic planet table: ascending by name',
119 $table
.tablesorter();
120 $table
.find( '.headerSort:eq(0)' ).click();
124 'Basic planet table: ascending by name a second time',
129 $table
.tablesorter();
130 $table
.find( '.headerSort:eq(0)' ).click();
134 'Basic planet table: descending by name',
137 reversed(ascendingName
),
139 $table
.tablesorter();
140 $table
.find( '.headerSort:eq(0)' ).click().click();
144 'Basic planet table: ascending radius',
149 $table
.tablesorter();
150 $table
.find( '.headerSort:eq(1)' ).click();
154 'Basic planet table: descending radius',
157 reversed(ascendingRadius
),
159 $table
.tablesorter();
160 $table
.find( '.headerSort:eq(1)' ).click().click();
167 'Bug 28775: German-style (dmy) short numeric dates',
169 [ // German-style dates are day-month-year
176 [ // Sorted by ascending date
184 mw
.config
.set( 'wgDefaultDateFormat', 'dmy' );
185 mw
.config
.set( 'wgContentLanguage', 'de' );
187 $table
.tablesorter();
188 $table
.find( '.headerSort:eq(0)' ).click();
193 'Bug 28775: American-style (mdy) short numeric dates',
195 [ // American-style dates are month-day-year
202 [ // Sorted by ascending date
210 mw
.config
.set( 'wgDefaultDateFormat', 'mdy' );
212 $table
.tablesorter();
213 $table
.find( '.headerSort:eq(0)' ).click();
218 // Some randomly generated fake IPs
229 // Sort order should go octet by octet
240 // Some randomly generated fake IPs
241 ['45.238.27.109/36'],
242 ['170.38.91.162/36'],
243 ['247.240.82.209/36'],
244 ['204.204.132.158/24'],
247 var ipv4CIDRSorted
= [
248 // Sort order should go octet by octet
249 ['45.238.27.109/36'],
250 ['170.38.91.162/24'],
251 ['170.38.91.162/36'],
252 ['204.204.132.158/24'],
253 ['247.240.82.209/36']
256 // Some randomly generated fake IPs
260 ['204.204.132.158/24'],
263 var ipv4MixedSorted
= [
264 // Sort order should go octet by octet
267 ['170.38.91.162/24'],
268 ['204.204.132.158/24'],
273 'Bug 17141: IPv4 address sorting',
278 $table
.tablesorter();
279 $table
.find( '.headerSort:eq(0)' ).click();
283 'Bug 17141: IPv4 address sorting (reverse)',
286 reversed(ipv4Sorted
),
288 $table
.tablesorter();
289 $table
.find( '.headerSort:eq(0)' ).click().click();
293 'Bug 34475: IPv4/CIDR address sorting',
298 $table
.tablesorter();
299 $table
.find( '.headerSort:eq(0)' ).click();
304 'Bug 34475: Mixed IPv4 and IP/CIDR address sorting',
309 $table
.tablesorter();
310 $table
.find( '.headerSort:eq(0)' ).click();
315 // Some words with Umlauts
326 var umlautWordsSorted
= [
327 // Some words with Umlauts
339 'Accented Characters with custom collation',
344 mw
.config
.set( 'tableSorterCollation', {
351 $table
.tablesorter();
352 $table
.find( '.headerSort:eq(0)' ).click();
356 var planetsRowspan
= [["Earth","6051.8"], jupiter
, ["Mars","6051.8"], mercury
, saturn
, venus
];
357 var planetsRowspanII
= [jupiter
, mercury
, saturn
, ['Venus', '6371.0'], venus
, ['Venus', '3390.0']];
360 'Basic planet table: same value for multiple rows via rowspan',
365 // Modify the table to have a multiuple-row-spanning cell:
366 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
367 $table
.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
368 // - Set rowspan for 2nd cell of 3rd row to 3.
369 // This covers the removed cell in the 4th and 5th row.
370 $table
.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
372 $table
.tablesorter();
373 $table
.find( '.headerSort:eq(0)' ).click();
377 'Basic planet table: Same value for multiple rows via rowspan II',
382 // Modify the table to have a multiuple-row-spanning cell:
383 // - Remove 1st cell of 4th row, and, 1st cell or 5th row.
384 $table
.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove();
385 // - Set rowspan for 1st cell of 3rd row to 3.
386 // This covers the removed cell in the 4th and 5th row.
387 $table
.find( 'tr:eq(2) td:eq(0)' ).prop( 'rowspan', '3' );
389 $table
.tablesorter();
390 $table
.find( '.headerSort:eq(0)' ).click();
394 var complexMDYDates
= [
395 // Some words with Umlauts
396 ['January, 19 2010'],
403 var complexMDYSorted
= [
407 ["January, 19 2010"],
412 'Complex date parsing I',
417 mw
.config
.set( 'wgDefaultDateFormat', 'mdy' );
419 $table
.tablesorter();
420 $table
.find( '.headerSort:eq(0)' ).click();
424 var ascendingNameLegacy
= ascendingName
.slice(0);
425 ascendingNameLegacy
[4] = ascendingNameLegacy
[5];
426 ascendingNameLegacy
.pop();
429 'Legacy compat with .sortbottom',
434 $table
.find( 'tr:last' ).addClass( 'sortbottom' );
435 $table
.tablesorter();
436 $table
.find( '.headerSort:eq(0)' ).click();
440 /** FIXME: the diff output is not very readeable. */
441 test( 'bug 32047 - caption must be before thead', function() {
444 '<table class="sortable">' +
445 '<caption>CAPTION</caption>' +
446 '<tr><th>THEAD</th></tr>' +
447 '<tr><td>A</td></tr>' +
448 '<tr><td>B</td></tr>' +
449 '<tr class="sortbottom"><td>TFOOT</td></tr>' +
452 $table
.tablesorter();
455 $table
.children( ).get( 0 ).nodeName
,
457 'First element after <thead> must be <caption> (bug 32047)'
461 test( 'data-sort-value attribute, when available, should override sorting position', function() {
464 // Simple example, one without data-sort-value which should be sorted at it's text.
466 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
468 '<tr><td>Cheetah</td></tr>' +
469 '<tr><td data-sort-value="Apple">Bird</td></tr>' +
470 '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
471 '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
472 '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
475 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
478 $table
.find( 'tbody > tr' ).each( function( i
, tr
) {
479 $( tr
).find( 'td' ).each( function( i
, td
) {
480 data
.push( { data
: $( td
).data( 'sort-value' ), text
: $( td
).text() } );
505 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
507 '<tr><td>D</td></tr>' +
508 '<tr><td data-sort-value="E">A</td></tr>' +
509 '<tr><td>B</td></tr>' +
510 '<tr><td>G</td></tr>' +
511 '<tr><td data-sort-value="F">C</td></tr>' +
514 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
517 $table
.find( 'tbody > tr' ).each( function( i
, tr
) {
518 $( tr
).find( 'td' ).each( function( i
, td
) {
519 data
.push( { data
: $( td
).data( 'sort-value' ), text
: $( td
).text() } );
561 tableTest( 'bug 8115: sort numbers with commas (ascending)',
562 ['Numbers'], numbers
, numbersAsc
,
564 $table
.tablesorter();
565 $table
.find( '.headerSort:eq(0)' ).click();
569 tableTest( 'bug 8115: sort numbers with commas (descending)',
570 ['Numbers'], numbers
, reversed(numbersAsc
),
572 $table
.tablesorter();
573 $table
.find( '.headerSort:eq(0)' ).click().click();
576 // TODO add numbers sorting tests for bug 8115 with a different language
603 tableTest( 'sort fractional numbers in all sorts and forms (ascending)',
604 ['Fractional numbers'], fractions
, fractionsAsc
,
606 $table
.tablesorter();
607 $table
.find( '.headerSort:eq(0)' ).click();
611 tableTest( 'sort fractional numbers in all sorts and forms (descending)',
612 ['Fractional numbers'], fractions
, reversed(fractionsAsc
),
614 $table
.tablesorter();
615 $table
.find( '.headerSort:eq(0)' ).click().click();
619 test( 'bug 32888 - Tables inside a tableheader cell', function() {
624 '<table class="sortable" id="32888">' +
625 '<tr><th>header<table id="32888-2">'+
626 '<tr><th>1</th><th>2</th></tr>' +
627 '</table></th></tr>' +
628 '<tr><td>A</td></tr>' +
629 '<tr><td>B</td></tr>' +
632 $table
.tablesorter();
635 $table
.find('> thead:eq(0) > tr > th.headerSort').length
,
637 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
640 $('#32888-2').find('th.headerSort').length
,
642 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'