From 14f74d141ab5580688bfd46d2f74c026e43ed967 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Wed, 1 Apr 2015 06:11:44 +0200 Subject: Update to MediaWiki 1.24.2 --- .../resources/jquery/jquery.tablesorter.test.js | 1327 ++++++++++++++++++++ 1 file changed, 1327 insertions(+) create mode 100644 tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js (limited to 'tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js') diff --git a/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js new file mode 100644 index 00000000..92dad9ff --- /dev/null +++ b/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js @@ -0,0 +1,1327 @@ +( function ( $, mw ) { + var header, + + // Data set "simple" + a1 = [ 'A', '1' ], + a2 = [ 'A', '2' ], + a3 = [ 'A', '3' ], + b1 = [ 'B', '1' ], + b2 = [ 'B', '2' ], + b3 = [ 'B', '3' ], + simple = [a2, b3, a1, a3, b2, b1], + simpleAsc = [a1, a2, a3, b1, b2, b3], + simpleDescasc = [b1, b2, b3, a1, a2, a3], + + // Data set "colspan" + aaa1 = [ 'A', 'A', 'A', '1' ], + aab5 = [ 'A', 'A', 'B', '5' ], + abc3 = [ 'A', 'B', 'C', '3' ], + bbc2 = [ 'B', 'B', 'C', '2' ], + caa4 = [ 'C', 'A', 'A', '4' ], + colspanInitial = [ aab5, aaa1, abc3, bbc2, caa4 ], + + // Data set "planets" + mercury = [ 'Mercury', '2439.7' ], + venus = [ 'Venus', '6051.8' ], + earth = [ 'Earth', '6371.0' ], + mars = [ 'Mars', '3390.0' ], + jupiter = [ 'Jupiter', '69911' ], + saturn = [ 'Saturn', '58232' ], + planets = [mercury, venus, earth, mars, jupiter, saturn], + planetsAscName = [earth, jupiter, mars, mercury, saturn, venus], + planetsAscRadius = [mercury, mars, venus, earth, saturn, jupiter], + planetsRowspan, + planetsRowspanII, + planetsAscNameLegacy, + + // Data set "ipv4" + ipv4 = [ + // Some randomly generated fake IPs + ['45.238.27.109'], + ['44.172.9.22'], + ['247.240.82.209'], + ['204.204.132.158'], + ['170.38.91.162'], + ['197.219.164.9'], + ['45.68.154.72'], + ['182.195.149.80'] + ], + ipv4Sorted = [ + // Sort order should go octet by octet + ['44.172.9.22'], + ['45.68.154.72'], + ['45.238.27.109'], + ['170.38.91.162'], + ['182.195.149.80'], + ['197.219.164.9'], + ['204.204.132.158'], + ['247.240.82.209'] + ], + + // Data set "umlaut" + umlautWords = [ + ['Günther'], + ['Peter'], + ['Björn'], + ['Bjorn'], + ['Apfel'], + ['Äpfel'], + ['Strasse'], + ['Sträßschen'] + ], + umlautWordsSorted = [ + ['Äpfel'], + ['Apfel'], + ['Björn'], + ['Bjorn'], + ['Günther'], + ['Peter'], + ['Sträßschen'], + ['Strasse'] + ], + + complexMDYDates = [ + ['January, 19 2010'], + ['April 21 1991'], + ['04 22 1991'], + ['5.12.1990'], + ['December 12 \'10'] + ], + complexMDYSorted = [ + ['5.12.1990'], + ['April 21 1991'], + ['04 22 1991'], + ['January, 19 2010'], + ['December 12 \'10'] + ], + + currencyUnsorted = [ + ['1.02 $'], + ['$ 3.00'], + ['€ 2,99'], + ['$ 1.00'], + ['$3.50'], + ['$ 1.50'], + ['€ 0.99'] + ], + currencySorted = [ + ['€ 0.99'], + ['$ 1.00'], + ['1.02 $'], + ['$ 1.50'], + ['$ 3.00'], + ['$3.50'], + // Comma's sort after dots + // Not intentional but test to detect changes + ['€ 2,99'] + ], + + numbers = [ + [ '12' ], + [ '7' ], + [ '13,000'], + [ '9' ], + [ '14' ], + [ '8.0' ] + ], + numbersAsc = [ + [ '7' ], + [ '8.0' ], + [ '9' ], + [ '12' ], + [ '14' ], + [ '13,000'] + ], + + correctDateSorting1 = [ + ['01 January 2010'], + ['05 February 2010'], + ['16 January 2010'] + ], + correctDateSortingSorted1 = [ + ['01 January 2010'], + ['16 January 2010'], + ['05 February 2010'] + ], + + correctDateSorting2 = [ + ['January 01 2010'], + ['February 05 2010'], + ['January 16 2010'] + ], + correctDateSortingSorted2 = [ + ['January 01 2010'], + ['January 16 2010'], + ['February 05 2010'] + ]; + + QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment( { + config: { + wgMonthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + wgMonthNamesShort: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + wgDefaultDateFormat: 'dmy', + wgSeparatorTransformTable: ['', ''], + wgDigitTransformTable: ['', ''], + wgContentLanguage: 'en' + } + } ) ); + + /** + * Create an HTML table from an array of row arrays containing text strings. + * First row will be header row. No fancy rowspan/colspan stuff. + * + * @param {String[]} header + * @param {String[][]} data + * @return jQuery + */ + function tableCreate( header, data ) { + var i, + $table = $( '
' ), + $thead = $table.find( 'thead' ), + $tbody = $table.find( 'tbody' ), + $tr = $( '' ); + + $.each( header, function ( i, str ) { + var $th = $( '' ); + $th.text( str ).appendTo( $tr ); + } ); + $tr.appendTo( $thead ); + + for ( i = 0; i < data.length; i++ ) { + /*jshint loopfunc: true */ + $tr = $( '' ); + $.each( data[i], function ( j, str ) { + var $td = $( '' ); + $td.text( str ).appendTo( $tr ); + } ); + $tr.appendTo( $tbody ); + } + return $table; + } + + /** + * Extract text from table. + * + * @param {jQuery} $table + * @return String[][] + */ + function tableExtract( $table ) { + var data = []; + + $table.find( 'tbody' ).find( 'tr' ).each( function ( i, tr ) { + var row = []; + $( tr ).find( 'td,th' ).each( function ( i, td ) { + row.push( $( td ).text() ); + } ); + data.push( row ); + } ); + return data; + } + + /** + * Run a table test by building a table with the given data, + * running some callback on it, then checking the results. + * + * @param {String} msg text to pass on to qunit for the comparison + * @param {String[]} header cols to make the table + * @param {String[][]} data rows/cols to make the table + * @param {String[][]} expected rows/cols to compare against at end + * @param {function($table)} callback something to do with the table before we compare + */ + function tableTest( msg, header, data, expected, callback ) { + QUnit.test( msg, 1, function ( assert ) { + var extracted, + $table = tableCreate( header, data ); + + // Give caller a chance to set up sorting and manipulate the table. + callback( $table ); + + // Table sorting is done synchronously; if it ever needs to change back + // to asynchronous, we'll need a timeout or a callback here. + extracted = tableExtract( $table ); + assert.deepEqual( extracted, expected, msg ); + } ); + } + + /** + * Run a table test by building a table with the given HTML, + * running some callback on it, then checking the results. + * + * @param {String} msg text to pass on to qunit for the comparison + * @param {String} HTML to make the table + * @param {String[][]} expected rows/cols to compare against at end + * @param {function($table)} callback something to do with the table before we compare + */ + function tableTestHTML( msg, html, expected, callback ) { + QUnit.test( msg, 1, function ( assert ) { + var extracted, + $table = $( html ); + + // Give caller a chance to set up sorting and manipulate the table. + if ( callback ) { + callback( $table ); + } else { + $table.tablesorter(); + $table.find( '#sortme' ).click(); + } + + // Table sorting is done synchronously; if it ever needs to change back + // to asynchronous, we'll need a timeout or a callback here. + extracted = tableExtract( $table ); + assert.deepEqual( extracted, expected, msg ); + } ); + } + + function reversed( arr ) { + // Clone array + var arr2 = arr.slice( 0 ); + + arr2.reverse(); + + return arr2; + } + + // Sample data set using planets named and their radius + header = [ 'Planet', 'Radius (km)']; + + tableTest( + 'Basic planet table: sorting initially - ascending by name', + header, + planets, + planetsAscName, + function ( $table ) { + $table.tablesorter( { sortList: [ + { 0: 'asc' } + ] } ); + } + ); + tableTest( + 'Basic planet table: sorting initially - descending by radius', + header, + planets, + reversed( planetsAscRadius ), + function ( $table ) { + $table.tablesorter( { sortList: [ + { 1: 'desc' } + ] } ); + } + ); + tableTest( + 'Basic planet table: ascending by name', + header, + planets, + planetsAscName, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Basic planet table: ascending by name a second time', + header, + planets, + planetsAscName, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Basic planet table: ascending by name (multiple clicks)', + header, + planets, + planetsAscName, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + $table.find( '.headerSort:eq(1)' ).click(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Basic planet table: descending by name', + header, + planets, + reversed( planetsAscName ), + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click().click(); + } + ); + tableTest( + 'Basic planet table: ascending radius', + header, + planets, + planetsAscRadius, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(1)' ).click(); + } + ); + tableTest( + 'Basic planet table: descending radius', + header, + planets, + reversed( planetsAscRadius ), + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(1)' ).click().click(); + } + ); + + header = [ 'column1', 'column2' ]; + + tableTest( + 'Sorting multiple columns by passing sort list', + header, + simple, + simpleAsc, + function ( $table ) { + $table.tablesorter( + { sortList: [ + { 0: 'asc' }, + { 1: 'asc' } + ] } + ); + } + ); + tableTest( + 'Sorting multiple columns by programmatically triggering sort()', + header, + simple, + simpleDescasc, + function ( $table ) { + $table.tablesorter(); + $table.data( 'tablesorter' ).sort( + [ + { 0: 'desc' }, + { 1: 'asc' } + ] + ); + } + ); + tableTest( + 'Reset to initial sorting by triggering sort() without any parameters', + header, + simple, + simpleAsc, + function ( $table ) { + $table.tablesorter( + { sortList: [ + { 0: 'asc' }, + { 1: 'asc' } + ] } + ); + $table.data( 'tablesorter' ).sort( + [ + { 0: 'desc' }, + { 1: 'asc' } + ] + ); + $table.data( 'tablesorter' ).sort(); + } + ); + tableTest( + 'Sort via click event after having initialized the tablesorter with initial sorting', + header, + simple, + simpleDescasc, + function ( $table ) { + $table.tablesorter( + { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] } + ); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Multi-sort via click event after having initialized the tablesorter with initial sorting', + header, + simple, + simpleAsc, + function ( $table ) { + $table.tablesorter( + { sortList: [ { 0: 'desc' }, { 1: 'desc' } ] } + ); + $table.find( '.headerSort:eq(0)' ).click(); + + // Pretend to click while pressing the multi-sort key + var event = $.Event( 'click' ); + event[$table.data( 'tablesorter' ).config.sortMultiSortKey] = true; + $table.find( '.headerSort:eq(1)' ).trigger( event ); + } + ); + QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) { + var $table = tableCreate( header, simple ); + $table.tablesorter( + { sortList: [ + { 0: 'desc' }, + { 1: 'asc' } + ] } + ); + $table.data( 'tablesorter' ).sort( [] ); + + assert.equal( + $table.find( 'th.headerSortUp' ).length + $table.find( 'th.headerSortDown' ).length, + 0, + 'No sort specific sort classes addign to header cells' + ); + + assert.equal( + $table.find( 'th' ).first().attr( 'title' ), + mw.msg( 'sort-ascending' ), + 'First header cell has default title' + ); + + assert.equal( + $table.find( 'th' ).first().attr( 'title' ), + $table.find( 'th' ).last().attr( 'title' ), + 'Both header cells\' titles match' + ); + } ); + + // Sorting with colspans + header = [ 'column1a', 'column1b', 'column1c', 'column2' ]; + + tableTest( 'Sorting with colspanned headers: spanned column', + header, + colspanInitial, + [ aaa1, aab5, abc3, bbc2, caa4 ], + function ( $table ) { + // Make colspanned header for test + $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( 'Sorting with colspanned headers: sort spanned column twice', + header, + colspanInitial, + [ caa4, bbc2, abc3, aab5, aaa1 ], + function ( $table ) { + // Make colspanned header for test + $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( 'Sorting with colspanned headers: subsequent column', + header, + colspanInitial, + [ aaa1, bbc2, abc3, caa4, aab5 ], + function ( $table ) { + // Make colspanned header for test + $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(1)' ).click(); + } + ); + tableTest( 'Sorting with colspanned headers: sort subsequent column twice', + header, + colspanInitial, + [ aab5, caa4, abc3, bbc2, aaa1 ], + function ( $table ) { + // Make colspanned header for test + $table.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove(); + $table.find( 'tr:eq(0) th:eq(0)' ).attr( 'colspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(1)' ).click(); + $table.find( '.headerSort:eq(1)' ).click(); + } + ); + + tableTest( + 'Basic planet table: one unsortable column', + header, + planets, + planets, + function ( $table ) { + $table.find( 'tr:eq(0) > th:eq(0)' ).addClass( 'unsortable' ); + + $table.tablesorter(); + $table.find( 'tr:eq(0) > th:eq(0)' ).click(); + } + ); + + // Regression tests! + tableTest( + 'Bug 28775: German-style (dmy) short numeric dates', + ['Date'], + [ + // German-style dates are day-month-year + ['11.11.2011'], + ['01.11.2011'], + ['02.10.2011'], + ['03.08.2011'], + ['09.11.2011'] + ], + [ + // Sorted by ascending date + ['03.08.2011'], + ['02.10.2011'], + ['01.11.2011'], + ['09.11.2011'], + ['11.11.2011'] + ], + function ( $table ) { + mw.config.set( 'wgDefaultDateFormat', 'dmy' ); + mw.config.set( 'wgContentLanguage', 'de' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + tableTest( + 'Bug 28775: American-style (mdy) short numeric dates', + ['Date'], + [ + // American-style dates are month-day-year + ['11.11.2011'], + ['01.11.2011'], + ['02.10.2011'], + ['03.08.2011'], + ['09.11.2011'] + ], + [ + // Sorted by ascending date + ['01.11.2011'], + ['02.10.2011'], + ['03.08.2011'], + ['09.11.2011'], + ['11.11.2011'] + ], + function ( $table ) { + mw.config.set( 'wgDefaultDateFormat', 'mdy' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + tableTest( + 'Bug 17141: IPv4 address sorting', + ['IP'], + ipv4, + ipv4Sorted, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Bug 17141: IPv4 address sorting (reverse)', + ['IP'], + ipv4, + reversed( ipv4Sorted ), + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click().click(); + } + ); + + tableTest( + 'Accented Characters with custom collation', + ['Name'], + umlautWords, + umlautWordsSorted, + function ( $table ) { + mw.config.set( 'tableSorterCollation', { + 'ä': 'ae', + 'ö': 'oe', + 'ß': 'ss', + 'ü': 'ue' + } ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + QUnit.test( 'Rowspan not exploded on init', 1, function ( assert ) { + var $table = tableCreate( header, planets ); + + // Modify the table to have a multiple-row-spanning cell: + // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row. + $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); + // - Set rowspan for 2nd cell of 3rd row to 3. + // This covers the removed cell in the 4th and 5th row. + $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); + + $table.tablesorter(); + + assert.equal( + $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowSpan' ), + 3, + 'Rowspan not exploded' + ); + } ); + + planetsRowspan = [ + [ 'Earth', '6051.8' ], + jupiter, + [ 'Mars', '6051.8' ], + mercury, + saturn, + venus + ]; + planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ]; + + tableTest( + 'Basic planet table: same value for multiple rows via rowspan', + header, + planets, + planetsRowspan, + function ( $table ) { + // Modify the table to have a multiple-row-spanning cell: + // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row. + $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); + // - Set rowspan for 2nd cell of 3rd row to 3. + // This covers the removed cell in the 4th and 5th row. + $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + tableTest( + 'Basic planet table: same value for multiple rows via rowspan (sorting initially)', + header, + planets, + planetsRowspan, + function ( $table ) { + // Modify the table to have a multiple-row-spanning cell: + // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row. + $table.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove(); + // - Set rowspan for 2nd cell of 3rd row to 3. + // This covers the removed cell in the 4th and 5th row. + $table.find( 'tr:eq(2) td:eq(1)' ).attr( 'rowspan', '3' ); + + $table.tablesorter( { sortList: [ + { 0: 'asc' } + ] } ); + } + ); + tableTest( + 'Basic planet table: Same value for multiple rows via rowspan II', + header, + planets, + planetsRowspanII, + function ( $table ) { + // Modify the table to have a multiple-row-spanning cell: + // - Remove 1st cell of 4th row, and, 1st cell or 5th row. + $table.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove(); + // - Set rowspan for 1st cell of 3rd row to 3. + // This covers the removed cell in the 4th and 5th row. + $table.find( 'tr:eq(2) td:eq(0)' ).attr( 'rowspan', '3' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + tableTest( + 'Complex date parsing I', + ['date'], + complexMDYDates, + complexMDYSorted, + function ( $table ) { + mw.config.set( 'wgDefaultDateFormat', 'mdy' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + tableTest( + 'Currency parsing I', + ['currency'], + currencyUnsorted, + currencySorted, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + planetsAscNameLegacy = planetsAscName.slice( 0 ); + planetsAscNameLegacy[4] = planetsAscNameLegacy[5]; + planetsAscNameLegacy.pop(); + + tableTest( + 'Legacy compat with .sortbottom', + header, + planets, + planetsAscNameLegacy, + function ( $table ) { + $table.find( 'tr:last' ).addClass( 'sortbottom' ); + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + QUnit.test( 'Test detection routine', 1, function ( assert ) { + var $table; + $table = $( + '' + + '' + + '' + + '' + + '' + + '
CAPTION
THEAD
1
text
' + ); + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + + assert.equal( + $table.data( 'tablesorter' ).config.parsers[0].id, + 'number', + 'Correctly detected column content skipping sortbottom' + ); + } ); + + /** FIXME: the diff output is not very readeable. */ + QUnit.test( 'bug 32047 - caption must be before thead', 1, function ( assert ) { + var $table; + $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '
CAPTION
THEAD
A
B
TFOOT
' + ); + $table.tablesorter(); + + assert.equal( + $table.children().get( 0 ).nodeName, + 'CAPTION', + 'First element after must be (bug 32047)' + ); + } ); + + QUnit.test( 'data-sort-value attribute, when available, should override sorting position', 3, function ( assert ) { + var $table, data; + + // Example 1: All cells except one cell without data-sort-value, + // which should be sorted at it's text content value. + $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Data
Cheetah
Bird
Ferret
Elephant
Dolphin
' + ); + $table.tablesorter().find( '.headerSort:eq(0)' ).click(); + + data = []; + $table.find( 'tbody > tr' ).each( function ( i, tr ) { + $( tr ).find( 'td' ).each( function ( i, td ) { + data.push( { + data: $( td ).data( 'sortValue' ), + text: $( td ).text() + } ); + } ); + } ); + + assert.deepEqual( data, [ + { + data: 'Apple', + text: 'Bird' + }, + { + data: 'Bananna', + text: 'Ferret' + }, + { + data: undefined, + text: 'Cheetah' + }, + { + data: 'Cherry', + text: 'Dolphin' + }, + { + data: 'Drupe', + text: 'Elephant' + } + ], 'Order matches expected order (based on data-sort-value attribute values)' ); + + // Example 2 + $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Data
D
A
B
G
C
' + ); + $table.tablesorter().find( '.headerSort:eq(0)' ).click(); + + data = []; + $table.find( 'tbody > tr' ).each( function ( i, tr ) { + $( tr ).find( 'td' ).each( function ( i, td ) { + data.push( { + data: $( td ).data( 'sortValue' ), + text: $( td ).text() + } ); + } ); + } ); + + assert.deepEqual( data, [ + { + data: undefined, + text: 'B' + }, + { + data: undefined, + text: 'D' + }, + { + data: 'E', + text: 'A' + }, + { + data: 'F', + text: 'C' + }, + { + data: undefined, + text: 'G' + } + ], 'Order matches expected order (based on data-sort-value attribute values)' ); + + // Example 3: Test that live changes are used from data-sort-value, + // even if they change after the tablesorter is constructed (bug 38152). + $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Data
D
A
B
G
C
' + ); + // initialize table sorter and sort once + $table + .tablesorter() + .find( '.headerSort:eq(0)' ).click(); + + // Change the sortValue data properties (bug 38152) + // - change data + $table.find( 'td:contains(A)' ).data( 'sortValue', 3 ); + // - add data + $table.find( 'td:contains(B)' ).data( 'sortValue', 1 ); + // - remove data, bring back attribute: 2 + $table.find( 'td:contains(G)' ).removeData( 'sortValue' ); + + // Now sort again (twice, so it is back at Ascending) + $table.find( '.headerSort:eq(0)' ).click(); + $table.find( '.headerSort:eq(0)' ).click(); + + data = []; + $table.find( 'tbody > tr' ).each( function ( i, tr ) { + $( tr ).find( 'td' ).each( function ( i, td ) { + data.push( { + data: $( td ).data( 'sortValue' ), + text: $( td ).text() + } ); + } ); + } ); + + assert.deepEqual( data, [ + { + data: 1, + text: 'B' + }, + { + data: 2, + text: 'G' + }, + { + data: 3, + text: 'A' + }, + { + data: undefined, + text: 'C' + }, + { + data: undefined, + text: 'D' + } + ], 'Order matches expected order, using the current sortValue in $.data()' ); + + } ); + + tableTest( 'bug 8115: sort numbers with commas (ascending)', + ['Numbers'], numbers, numbersAsc, + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + tableTest( 'bug 8115: sort numbers with commas (descending)', + ['Numbers'], numbers, reversed( numbersAsc ), + function ( $table ) { + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click().click(); + } + ); + // TODO add numbers sorting tests for bug 8115 with a different language + + QUnit.test( 'bug 32888 - Tables inside a tableheader cell', 2, function ( assert ) { + var $table; + $table = $( + '' + + '' + + '' + + '' + + '
header' + + '' + + '
12
A
B
' + ); + $table.tablesorter(); + + assert.equal( + $table.find( '> thead:eq(0) > tr > th.headerSort' ).length, + 1, + 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)' + ); + assert.equal( + $( '#mw-bug-32888-2' ).find( 'th.headerSort' ).length, + 0, + 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)' + ); + } ); + + tableTest( + 'Correct date sorting I', + ['date'], + correctDateSorting1, + correctDateSortingSorted1, + function ( $table ) { + mw.config.set( 'wgDefaultDateFormat', 'mdy' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + tableTest( + 'Correct date sorting II', + ['date'], + correctDateSorting2, + correctDateSortingSorted2, + function ( $table ) { + mw.config.set( 'wgDefaultDateFormat', 'dmy' ); + + $table.tablesorter(); + $table.find( '.headerSort:eq(0)' ).click(); + } + ); + + QUnit.test( 'Sorting images using alt text', 1, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '
THEAD
2
1
' + ); + $table.tablesorter().find( '.headerSort:eq(0)' ).click(); + + assert.equal( + $table.find( 'td' ).first().text(), + '1', + 'Applied correct sorting order' + ); + } ); + + QUnit.test( 'Sorting images using alt text (complex)', 1, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
THEAD
DA
CC
AF
AE
AD
AC
' + ); + $table.tablesorter().find( '.headerSort:eq(0)' ).click(); + + assert.equal( + $table.find( 'td' ).text(), + 'CDEFCCA', + 'Applied correct sorting order' + ); + } ); + + QUnit.test( 'Sorting images using alt text (with format autodetection)', 1, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '
THEAD
17
16
5
4
' + ); + $table.tablesorter().find( '.headerSort:eq(0)' ).click(); + + assert.equal( + $table.find( 'td' ).text(), + '4517', + 'Applied correct sorting order' + ); + } ); + + QUnit.test( 'bug 38911 - The row with the largest amount of columns should receive the sort indicators', 3, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
A1B2a
B2bC2b
AAaAb
BBaBb
' + ); + $table.tablesorter(); + + assert.equal( + $table.find( '#A1' ).attr( 'class' ), + 'headerSort', + 'The first column of the first row should be sortable' + ); + assert.equal( + $table.find( '#B2b' ).attr( 'class' ), + 'headerSort', + 'The th element of the 2nd row of the 2nd column should be sortable' + ); + assert.equal( + $table.find( '#C2b' ).attr( 'class' ), + 'headerSort', + 'The th element of the 2nd row of the 3rd column should be sortable' + ); + } ); + + QUnit.test( 'rowspans in table headers should prefer the last row when rows are equal in length', 2, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
A1B2a
B2b
AAa
BBa
' + ); + $table.tablesorter(); + + assert.equal( + $table.find( '#A1' ).attr( 'class' ), + 'headerSort', + 'The first column of the first row should be sortable' + ); + assert.equal( + $table.find( '#B2b' ).attr( 'class' ), + 'headerSort', + 'The th element of the 2nd row of the 2nd column should be sortable' + ); + } ); + + QUnit.test( 'holes in the table headers should not throw JS errors', 2, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
A1B1C1
A2
AAaAaa
BBaBbb
' + ); + $table.tablesorter(); + assert.equal( $table.find( '#A2' ).prop( 'headerIndex' ), + undefined, + 'A2 should not be a sort header' + ); + assert.equal( $table.find( '#C1' ).prop( 'headerIndex' ), + 2, + 'C1 should be a sort header' + ); + } ); + + // bug 53527 + QUnit.test( 'td cells in thead should not be taken into account for longest row calculation', 2, function ( assert ) { + var $table = $( + '' + + '' + + '' + + '' + + '' + + '
A1B1C1
A2B2C2
' + ); + $table.tablesorter(); + assert.equal( $table.find( '#C2' ).prop( 'headerIndex' ), + 2, + 'C2 should be a sort header' + ); + assert.equal( $table.find( '#C1' ).prop( 'headerIndex' ), + undefined, + 'C1 should not be a sort header' + ); + } ); + + // bug 41889 - exploding rowspans in more complex cases + tableTestHTML( + 'Rowspan exploding with row headers', + '' + + '' + + '' + + '' + + '' + + '
nfoobarbaz
1foobarbaz
2baz
', + [ + [ '1', 'foo', 'bar', 'baz' ], + [ '2', 'foo', 'bar', 'baz' ] + ] + ); + + // bug 53211 - exploding rowspans in more complex cases + QUnit.test( + 'Rowspan exploding with row headers and colspans', 1, function ( assert ) { + var $table = $( '' + + '' + + '' + + '' + + '' + + '' + + '
nfoobaz
foobar
1foobarbaz
2foobarbaz
' ); + + $table.tablesorter(); + assert.equal( $table.find( 'tr:eq(1) th:eq(1)').prop('headerIndex'), + 2, + 'Incorrect index of sort header' ); + } + ); + + tableTestHTML( + 'Rowspan exploding with colspanned cells', + '' + + '' + + '' + + '' + + '' + + '
nfoobarbaz
1foobarbaz
2foobar
', + [ + [ '1', 'foo', 'bar', 'baz' ], + [ '2', 'foobar', 'baz' ] + ] + ); + + tableTestHTML( + 'Rowspan exploding with colspanned cells (2)', + '' + + '' + + '' + + '' + + '' + + '
nfoobarbazquux
1foobarbazquux
2foobarquux
', + [ + [ '1', 'foo', 'bar', 'baz', 'quux' ], + [ '2', 'foobar', 'baz', 'quux' ] + ] + ); + + tableTestHTML( + 'Rowspan exploding with rightmost rows spanning most', + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
nfoobar
1foobar
2
3foo
4
', + [ + [ '1', 'foo', 'bar' ], + [ '2', 'foo', 'bar' ], + [ '3', 'foo', 'bar' ], + [ '4', 'foo', 'bar' ] + ] + ); + + tableTestHTML( + 'Rowspan exploding with rightmost rows spanning most (2)', + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
nfoobarbaz
1foobarbaz
2baz
3foobaz
4baz
', + [ + [ '1', 'foo', 'bar', 'baz' ], + [ '2', 'foo', 'bar', 'baz' ], + [ '3', 'foo', 'bar', 'baz' ], + [ '4', 'foo', 'bar', 'baz' ] + ] + ); + + tableTestHTML( + 'Rowspan exploding with row-and-colspanned cells', + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
nfoo1foo2barbaz
1foo1foo2barbaz
2baz
3foobaz
4baz
', + [ + [ '1', 'foo1', 'foo2', 'bar', 'baz' ], + [ '2', 'foo1', 'foo2', 'bar', 'baz' ], + [ '3', 'foo', 'bar', 'baz' ], + [ '4', 'foo', 'bar', 'baz' ] + ] + ); + + tableTestHTML( + 'Rowspan exploding with uneven rowspan layout', + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
nfoo1foo2foo3barbaz
1foo1foo2foo3barbaz
2barbaz
3foo1foo2foo3baz
4baz
', + [ + [ '1', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ], + [ '2', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ], + [ '3', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ], + [ '4', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ] + ] + ); + +}( jQuery, mediaWiki ) ); -- cgit v1.2.3-54-g00ecf