Merge "TableSorter: Fix column order when collecting headers"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sat, 1 Mar 2014 17:06:59 +0000 (17:06 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 1 Mar 2014 17:06:59 +0000 (17:06 +0000)
1  2 
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js

  ( function ( $, mw ) {
 -      /*jshint onevar: false */
 +      var config, header,
  
 -      var config = {
 +              // 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']
 +              ];
 +
 +      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',
         */
        function tableTest( msg, header, data, expected, callback ) {
                QUnit.test( msg, 1, function ( assert ) {
 -                      var $table = tableCreate( header, data );
 +                      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.
 -                      var extracted = tableExtract( $table );
 +                      extracted = tableExtract( $table );
                        assert.deepEqual( extracted, expected, msg );
                } );
        }
         */
        function tableTestHTML( msg, html, expected, callback ) {
                QUnit.test( msg, 1, function ( assert ) {
 -                      var $table = $( html );
 +                      var extracted,
 +                              $table = $( html );
  
                        // Give caller a chance to set up sorting and manipulate the table.
                        if ( callback ) {
  
                        // Table sorting is done synchronously; if it ever needs to change back
                        // to asynchronous, we'll need a timeout or a callback here.
 -                      var extracted = tableExtract( $table );
 +                      extracted = tableExtract( $table );
                        assert.deepEqual( extracted, expected, msg );
                } );
        }
        }
  
        // Sample data set using planets named and their radius
 -      var header = [ 'Planet' , 'Radius (km)'],
 -              mercury = [ 'Mercury', '2439.7' ],
 -              venus = [ 'Venus'  , '6051.8' ],
 -              earth = [ 'Earth'  , '6371.0' ],
 -              mars = [ 'Mars'   , '3390.0' ],
 -              jupiter = [ 'Jupiter', '69911' ],
 -              saturn = [ 'Saturn' , '58232' ];
 -
 -      // Initial data set
 -      var planets = [mercury, venus, earth, mars, jupiter, saturn];
 -      var ascendingName = [earth, jupiter, mars, mercury, saturn, venus];
 -      var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter];
 +      header = [ 'Planet', 'Radius (km)'];
  
        tableTest(
                'Basic planet table: sorting initially - ascending by name',
                header,
                planets,
 -              ascendingName,
 +              planetsAscName,
                function ( $table ) {
                        $table.tablesorter( { sortList: [
                                { 0: 'asc' }
                'Basic planet table: sorting initially - descending by radius',
                header,
                planets,
 -              reversed( ascendingRadius ),
 +              reversed( planetsAscRadius ),
                function ( $table ) {
                        $table.tablesorter( { sortList: [
                                { 1: 'desc' }
                'Basic planet table: ascending by name',
                header,
                planets,
 -              ascendingName,
 +              planetsAscName,
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                'Basic planet table: ascending by name a second time',
                header,
                planets,
 -              ascendingName,
 +              planetsAscName,
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                'Basic planet table: ascending by name (multiple clicks)',
                header,
                planets,
 -              ascendingName,
 +              planetsAscName,
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                'Basic planet table: descending by name',
                header,
                planets,
 -              reversed( ascendingName ),
 +              reversed( planetsAscName ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                'Basic planet table: ascending radius',
                header,
                planets,
 -              ascendingRadius,
 +              planetsAscRadius,
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(1)' ).click();
                'Basic planet table: descending radius',
                header,
                planets,
 -              reversed( ascendingRadius ),
 +              reversed( planetsAscRadius ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(1)' ).click().click();
                }
        );
  
 -      // Sample data set to test multiple column sorting
 -      header = [ 'column1' , 'column2'];
 -      var
 -              a1 = [ 'A', '1' ],
 -              a2 = [ 'A', '2' ],
 -              a3 = [ 'A', '3' ],
 -              b1 = [ 'B', '1' ],
 -              b2 = [ 'B', '2' ],
 -              b3 = [ 'B', '3' ];
 -      var initial = [a2, b3, a1, a3, b2, b1];
 -      var asc = [a1, a2, a3, b1, b2, b3];
 -      var descasc = [b1, b2, b3, a1, a2, a3];
 +      header = [ 'column1', 'column2' ];
  
        tableTest(
                'Sorting multiple columns by passing sort list',
                header,
 -              initial,
 -              asc,
 +              simple,
 +              simpleAsc,
                function ( $table ) {
                        $table.tablesorter(
                                { sortList: [
        tableTest(
                'Sorting multiple columns by programmatically triggering sort()',
                header,
 -              initial,
 -              descasc,
 +              simple,
 +              simpleDescasc,
                function ( $table ) {
                        $table.tablesorter();
                        $table.data( 'tablesorter' ).sort(
        tableTest(
                'Reset to initial sorting by triggering sort() without any parameters',
                header,
 -              initial,
 -              asc,
 +              simple,
 +              simpleAsc,
                function ( $table ) {
                        $table.tablesorter(
                                { sortList: [
        tableTest(
                'Sort via click event after having initialized the tablesorter with initial sorting',
                header,
 -              initial,
 -              descasc,
 +              simple,
 +              simpleDescasc,
                function ( $table ) {
                        $table.tablesorter(
                                { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
        tableTest(
                'Multi-sort via click event after having initialized the tablesorter with initial sorting',
                header,
 -              initial,
 -              asc,
 +              simple,
 +              simpleAsc,
                function ( $table ) {
                        $table.tablesorter(
                                { sortList: [ { 0: 'desc' }, { 1: 'desc' } ] }
                }
        );
        QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) {
 -              var $table = tableCreate( header, initial );
 +              var $table = tableCreate( header, simple );
                $table.tablesorter(
                        { sortList: [
                                { 0: 'desc' },
        } );
  
        // Sorting with colspans
 -      header = [ 'column1a' , 'column1b', 'column1c', 'column2' ];
 -      var
 -              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' ];
 -      // initial is already declared above
 -      initial = [ aab5, aaa1, abc3, bbc2, caa4 ];
 +      header = [ 'column1a', 'column1b', 'column1c', 'column2' ];
 +
        tableTest( 'Sorting with colspanned headers: spanned column',
                header,
 -              initial,
 +              colspanInitial,
                [ aaa1, aab5, abc3, bbc2, caa4 ],
                function ( $table ) {
                        // Make colspanned header for test
        );
        tableTest( 'Sorting with colspanned headers: sort spanned column twice',
                header,
 -              initial,
 +              colspanInitial,
                [ caa4, bbc2, abc3, aab5, aaa1 ],
                function ( $table ) {
                        // Make colspanned header for test
        );
        tableTest( 'Sorting with colspanned headers: subsequent column',
                header,
 -              initial,
 +              colspanInitial,
                [ aaa1, bbc2, abc3, caa4, aab5 ],
                function ( $table ) {
                        // Make colspanned header for test
        );
        tableTest( 'Sorting with colspanned headers: sort subsequent column twice',
                header,
 -              initial,
 +              colspanInitial,
                [ aab5, caa4, abc3, bbc2, aaa1 ],
                function ( $table ) {
                        // Make colspanned header for test
                }
        );
  
 -
        tableTest(
                'Basic planet table: one unsortable column',
                header,
                }
        );
  
 -      var 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']
 -      ];
 -      var 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']
 -      ];
 -
        tableTest(
                'Bug 17141: IPv4 address sorting',
                ['IP'],
                }
        );
  
 -      var umlautWords = [
 -              // Some words with Umlauts
 -              ['Günther'],
 -              ['Peter'],
 -              ['Björn'],
 -              ['Bjorn'],
 -              ['Apfel'],
 -              ['Äpfel'],
 -              ['Strasse'],
 -              ['Sträßschen']
 -      ];
 -
 -      var umlautWordsSorted = [
 -              // Some words with Umlauts
 -              ['Äpfel'],
 -              ['Apfel'],
 -              ['Björn'],
 -              ['Bjorn'],
 -              ['Günther'],
 -              ['Peter'],
 -              ['Sträßschen'],
 -              ['Strasse']
 -      ];
 -
        tableTest(
                'Accented Characters with custom collation',
                ['Name'],
                );
        } );
  
 -      var planetsRowspan = [
 +      planetsRowspan = [
                [ 'Earth', '6051.8' ],
                jupiter,
                [ 'Mars', '6051.8' ],
                saturn,
                venus
        ];
 -      var planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
 +      planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
  
        tableTest(
                'Basic planet table: same value for multiple rows via rowspan',
                }
        );
  
 -      var complexMDYDates = [
 -              // Some words with Umlauts
 -              ['January, 19 2010'],
 -              ['April 21 1991'],
 -              ['04 22 1991'],
 -              ['5.12.1990'],
 -              ['December 12 \'10']
 -      ];
 -
 -      var complexMDYSorted = [
 -              ['5.12.1990'],
 -              ['April 21 1991'],
 -              ['04 22 1991'],
 -              ['January, 19 2010'],
 -              ['December 12 \'10']
 -      ];
 -
        tableTest(
                'Complex date parsing I',
                ['date'],
                }
        );
  
 -      var currencyUnsorted = [
 -              ['1.02 $'],
 -              ['$ 3.00'],
 -              ['€ 2,99'],
 -              ['$ 1.00'],
 -              ['$3.50'],
 -              ['$ 1.50'],
 -              ['€ 0.99']
 -      ];
 -
 -      var 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']
 -      ];
 -
        tableTest(
                'Currency parsing I',
                ['currency'],
                }
        );
  
 -      var ascendingNameLegacy = ascendingName.slice( 0 );
 -      ascendingNameLegacy[4] = ascendingNameLegacy[5];
 -      ascendingNameLegacy.pop();
 +      planetsAscNameLegacy = planetsAscName.slice( 0 );
 +      planetsAscNameLegacy[4] = planetsAscNameLegacy[5];
 +      planetsAscNameLegacy.pop();
  
        tableTest(
                'Legacy compat with .sortbottom',
                header,
                planets,
 -              ascendingNameLegacy,
 +              planetsAscNameLegacy,
                function ( $table ) {
                        $table.find( 'tr:last' ).addClass( 'sortbottom' );
                        $table.tablesorter();
  
        } );
  
 -      var numbers = [
 -              [ '12'    ],
 -              [  '7'    ],
 -              [ '13,000'],
 -              [  '9'    ],
 -              [ '14'    ],
 -              [  '8.0'  ]
 -      ];
 -      var numbersAsc = [
 -              [  '7'    ],
 -              [  '8.0'  ],
 -              [  '9'    ],
 -              [ '12'    ],
 -              [ '14'    ],
 -              [ '13,000']
 -      ];
 -
        tableTest( 'bug 8115: sort numbers with commas (ascending)',
                ['Numbers'], numbers, numbersAsc,
                function ( $table ) {
                );
        } );
  
 -
 -      var correctDateSorting1 = [
 -              ['01 January 2010'],
 -              ['05 February 2010'],
 -              ['16 January 2010']
 -      ];
 -
 -      var correctDateSortingSorted1 = [
 -              ['01 January 2010'],
 -              ['16 January 2010'],
 -              ['05 February 2010']
 -      ];
 -
        tableTest(
                'Correct date sorting I',
                ['date'],
                }
        );
  
 -      var correctDateSorting2 = [
 -              ['January 01 2010'],
 -              ['February 05 2010'],
 -              ['January 16 2010']
 -      ];
 -
 -      var correctDateSortingSorted2 = [
 -              ['January 01 2010'],
 -              ['January 16 2010'],
 -              ['February 05 2010']
 -      ];
 -
        tableTest(
                'Correct date sorting II',
                ['date'],
                );
        } );
  
+       QUnit.test( 'holes in the table headers should not throw JS errors', 2, function ( assert ) {
+               var $table = $(
+                       '<table class="sortable">' +
+                               '<thead>' +
+                               '<tr><th id="A1">A1</th><th>B1</th><th id="C1" rowspan="2">C1</th></tr>' +
+                               '<tr><th id="A2">A2</th></tr>' +
+                               '</thead>' +
+                               '<tr><td>A</td><td>Aa</td><td>Aaa</td></tr>' +
+                               '<tr><td>B</td><td>Ba</td><td>Bbb</td></tr>' +
+                               '</table>'
+               );
+               $table.tablesorter();
+               assert.equal( 0,
+                       $table.find( '#A2' ).prop( 'headerIndex' ),
+                       'A2 should be a sort header'
+               );
+               assert.equal( 1, // should be 2
+                       $table.find( '#C1' ).prop( 'headerIndex' ),
+                       'C1 should be a sort header, but will sort the wrong column'
+               );
+       } );
        // bug 41889 - exploding rowspans in more complex cases
        tableTestHTML(
                'Rowspan exploding with row headers',
                ]
        );
  
+       // bug 53211 - exploding rowspans in more complex cases
+       QUnit.test(
+               'Rowspan exploding with row headers and colspans', 1, function ( assert ) {
+               var $table = $( '<table class="sortable">' +
+                       '<thead><tr><th rowspan="2">n</th><th colspan="2">foo</th><th rowspan="2">baz</th></tr>' +
+                       '<tr><th>foo</th><th>bar</th></tr></thead>' +
+                       '<tbody>' +
+                       '<tr><td>1</td><td>foo</td><td>bar</td><td>baz</td></tr>' +
+                       '<tr><td>2</td><td>foo</td><td>bar</td><td>baz</td></tr>' +
+                       '</tbody></table>' );
+                       $table.tablesorter();
+                       assert.equal( 2, $table.find( 'tr:eq(1) th:eq(1)').prop('headerIndex'), 'Incorrect index of sort header' );
+               }
+       );
        tableTestHTML(
                'Rowspan exploding with colspanned cells',
                '<table class="sortable">' +