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