jenkins-bot has submitted this change and it was merged.

Change subject: Use SMW\TableFormatter for the table query printer 
(SMWTableResultPrinter)
......................................................................


Use SMW\TableFormatter for the table query printer (SMWTableResultPrinter)

SMWTableResultPrinter has a CRAP of 478 which puts this printer into
a category of a potential hazardous printer that can be broken easily.

Doing data gathering and doing formatting are fundamentally two
different things and should not be mixed as it increases complexity.
Having attributes being dependent on data they present is necessary
but HTML related formatting has nothing to do with the data itself
therefore it is the wrong place and a formatting class should be used
instead.

It doesn't solve the inherent problem of the SMWTableResultPrinter class
but it allows for seperate unit testing and coverage.

SMW\TableFormatter
Code overage: 100%
CRAP: 25

SMWTableResultPrinter
Code coverage: 33.33%
CRAP: before 478 after 352

@code
$tableFormatter = new SMW\TableFormatter();

// Setup the header
$tableFormatter->addTableHeader( 'Foo' )
$tableFormatter->addTableHeader( 'Bar' )

// Add row
$tableFormatter->addTableCell( 'Lula' )
$tableFormatter->addTableCell( 'Lala' )
$tableFormatter->addTableRow()
...

// Get table
$tableFormatter->getTable() // Standard table
$tableFormatter->transpose()->getTable() // Transposed table
$tableFormatter->transpose( false )->getTable() // Standard table
@endcode

## Note
SMW\TableFormatter is used for the Factbox as well.

[1] http://www.semantic-mediawiki.org/wiki/CRAP

Change-Id: I11c0057669e0a18c7b573ef64b21414fcb202b01
---
M includes/Setup.php
A includes/formatters/TableFormatter.php
M includes/queryprinters/SMW_QP_Table.php
A tests/phpunit/includes/formatters/TableFormatterTest.php
4 files changed, 768 insertions(+), 74 deletions(-)

Approvals:
  Mwjames: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/Setup.php b/includes/Setup.php
index 883a43b..4e4b36b 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -154,6 +154,7 @@
        $wgAutoloadClasses['SMW\ArrayFormatter']           = $incDir . 
'formatters/ArrayFormatter.php';
        $wgAutoloadClasses['SMW\ParserParameterFormatter'] = $incDir . 
'formatters/ParserParameterFormatter.php';
        $wgAutoloadClasses['SMW\MessageFormatter']         = $incDir . 
'formatters/MessageFormatter.php';
+       $wgAutoloadClasses['SMW\TableFormatter']           = $incDir . 
'formatters/TableFormatter.php';
 
        // Exceptions
        $wgAutoloadClasses['SMW\StoreInstanceException']       = $incDir . 
'/exceptions/StoreInstanceException.php';
diff --git a/includes/formatters/TableFormatter.php 
b/includes/formatters/TableFormatter.php
new file mode 100644
index 0000000..3bde53e
--- /dev/null
+++ b/includes/formatters/TableFormatter.php
@@ -0,0 +1,334 @@
+<?php
+
+namespace SMW;
+
+use Html;
+
+/**
+ * Class handling Html table formatting
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.9
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @author mwjames
+ */
+
+/**
+ * Class handling Html table formatting
+ *
+ * @ingroup Formatter
+ */
+class TableFormatter {
+
+       /** @var array */
+       protected $headerItems = array();
+
+       /** @var array */
+       protected $tableRows = array();
+       protected $rawRows = array();
+
+       /** @var array */
+       protected $tableHeaders = array();
+       protected $rawHeaders = array();
+
+       /** @var array */
+       protected $tableCells = array();
+
+       /** @var boolean */
+       protected $transpose = false;
+
+       /**
+        * @par Example:
+        * @code
+        *  $tableFormatter = new SMW\TableFormatter();
+        *
+        *  // Setup the header
+        *  $tableFormatter->addTableHeader( 'Foo' )
+        *  $tableFormatter->addTableHeader( 'Bar' )
+        *
+        *  // Add row
+        *  $tableFormatter->addTableCell( 'Lula' )
+        *  $tableFormatter->addTableCell( 'Lala' )
+        *  $tableFormatter->addTableRow()
+        *  ...
+        *
+        *  // Get table
+        *  $tableFormatter->getTable() // Standard table
+        *  $tableFormatter->transpose()->getTable() // Transposed table
+        *  $tableFormatter->transpose( false )->getTable() // Standard table
+        * @endcode
+        *
+        * @since 1.9
+        *
+        * @param boolean $htmlContext
+        */
+       public function __construct( $htmlContext = false ) {
+               $this->htmlContext = $htmlContext;
+       }
+
+       /**
+        * Sets if the table should be transposed
+        *
+        * @since 1.9
+        *
+        * @param boolean $transpose
+        *
+        * @return TableFormatter
+        */
+       public function transpose( $transpose = true ) {
+               $this->transpose = $transpose;
+               return $this;
+       }
+
+       /**
+        * Adds an arbitrary header item to an internal array
+        *
+        * @since 1.9
+        *
+        * @param string $element
+        * @param string $content
+        * @param array $attributes
+        *
+        * @return string
+        */
+       public function addHeaderItem( $element, $content = '', $attributes = 
array() ) {
+               $this->headerItems[] = Html::rawElement( $element, $attributes, 
$content );
+       }
+
+       /**
+        * Returns concatenated header items
+        *
+        * @since 1.9
+        *
+        * @return string
+        */
+       public function getHeaderItems() {
+               return implode( '', $this->headerItems );
+       }
+
+       /**
+        * Collects and adds table cells
+        *
+        * @since 1.9
+        *
+        * @param string $content
+        * @param array $attributes
+        *
+        * @return TableFormatter
+        */
+       public function addTableCell( $content = '', $attributes = array() ) {
+               if ( $content !== '' ) {
+                       $this->tableCells[] = $this->getCell( $content, 
$attributes );
+               }
+               return $this;
+       }
+
+       /**
+        * Collects and adds table headers
+        *
+        * @since 1.9
+        *
+        * @param string $content
+        * @param array $attributes
+        *
+        * @return TableFormatter
+        */
+       public function addTableHeader( $content = '', $attributes = array() ) {
+               if ( $content !== '' ) {
+                       $this->rawHeaders[] = array( 'content' => $content, 
'attributes' => $attributes );
+               }
+               return $this;
+       }
+
+       /**
+        * Build a row from invoked cells, copy them into a new associated array
+        * and delete those cells as they are now part of a row
+        *
+        * @par Example:
+        * @code
+        *  ...
+        *  $tableFormatter->addTableCell( 'Lula' )->addTableCell( 'Lala' 
)->addTableRow()
+        *  ...
+        * @endcode
+        *
+        * @since 1.9
+        *
+        * @param array $attributes
+        *
+        * @return TableFormatter
+        */
+       public function addTableRow( $attributes = array() ) {
+               if ( $this->tableCells !== array() ) {
+                       $this->rawRows[] = array( 'cells' => $this->tableCells, 
'attributes' => $attributes );
+                       $this->tableCells = array();
+               }
+               return $this;
+       }
+
+       /**
+        * Internal method for returning a table row definition
+        *
+        * @since 1.9
+        *
+        * @param string $content
+        * @param array $attributes
+        *
+        * @return string
+        */
+       protected function getRow( $content = '', $attributes = array() ) {
+               $alternate = count( $this->tableRows ) % 2 == 0 ? 'row-odd' : 
'row-even';
+
+               if ( isset( $attributes['class'] ) ) {
+                       $attributes['class'] = $attributes['class'] . ' ' . 
$alternate;
+               } else {
+                       $attributes['class'] = $alternate;
+               }
+
+               return Html::rawElement( 'tr', $attributes , $content );
+       }
+
+       /**
+        * Internal method for returning a table cell definition
+        *
+        * @since 1.9
+        *
+        * @param string $content
+        * @param array $attributes
+        *
+        * @return string
+        */
+       protected function getCell( $content = '', $attributes = array() ) {
+               return Html::rawElement( 'td', $attributes, $content );
+       }
+
+       /**
+        * Internal method for returning a table header definition
+        *
+        * @since 1.9
+        *
+        * @param string $content
+        * @param array $attributes
+        *
+        * @return string
+        */
+       protected function getHeader( $content = '', $attributes = array() ) {
+               return Html::rawElement( 'th', $attributes, $content );
+       }
+
+       /**
+        * Returns table headers as concatenated string
+        *
+        * @since 1.9
+        *
+        * @return string
+        */
+       protected function getTableHeader() {
+               return $this->htmlContext ? Html::rawElement( 'thead', array(), 
implode( '', $this->tableHeaders ) ) : implode( '', $this->tableHeaders );
+       }
+
+       /**
+        * Returns table rows as concatenated string
+        *
+        * @since 1.9
+        *
+        * @return string
+        */
+       protected function getTableRows() {
+               return $this->htmlContext ? Html::rawElement( 'tbody', array(), 
implode( '', $this->tableRows ) ) : implode( '', $this->tableRows );
+       }
+
+       /**
+        * Returns a standard table
+        *
+        * @since 1.9
+        *
+        * @return string
+        */
+       protected function getStandardTable() {
+               $this->tableHeaders = array();
+               $this->tableRows = array();
+
+               foreach( $this->rawHeaders as $i => $header ) {
+                       $this->tableHeaders[] = $this->getHeader( 
$header['content'], $header['attributes'] );
+               }
+
+               foreach( $this->rawRows as $row ) {
+                       $this->tableRows[] = $this->getRow( implode( '', 
$row['cells'] ), $row['attributes'] );
+               }
+
+               return $this->getTableHeader() . $this->getTableRows();
+       }
+
+       /**
+        * Returns a transposed table
+        *
+        * @note A table will only be transposed if header elements are 
available
+        *
+        * @since 1.9
+        *
+        * @return string
+        */
+       protected function getTransposedTable() {
+               $this->tableRows = array();
+
+               foreach( $this->rawHeaders as $hIndex => $header ) {
+                       $cells = array();
+                       $headerItem =  $this->getHeader( $header['content'], 
$header['attributes'] );
+
+                       foreach( $this->rawRows as $rIndex => $row ) {
+                               $cells[] = isset( $row['cells'][$hIndex] ) ? 
$row['cells'][$hIndex] : $this->getCell( '' );
+                       }
+
+                       // Collect new rows
+                       $this->tableRows[] = $this->getRow( $headerItem . 
implode( '', $cells ) );
+               }
+
+               return $this->getTableHeader() . $this->getTableRows();
+       }
+
+       /**
+        * Returns a table
+        *
+        * @par Example:
+        * @code
+        *  ...
+        *  $tableFormatter->getTable() // Standard table
+        *  $tableFormatter->transpose()->getTable() // Transposed table
+        *  $tableFormatter->transpose( false )->getTable() // Standard table
+        *  ...
+        * @endcode
+        *
+        * @since 1.9
+        *
+        * @param array $attributes
+        *
+        * @return string
+        */
+       public function getTable( $attributes = array() ) {
+
+               $table = $this->transpose ? $this->getTransposedTable() : 
$this->getStandardTable();
+
+               if ( $table !== '' ) {
+                       return Html::rawElement( 'table', $attributes, $table );
+               }
+
+               return '';
+       }
+}
diff --git a/includes/queryprinters/SMW_QP_Table.php 
b/includes/queryprinters/SMW_QP_Table.php
index 30c3ff8..d8d8e68 100644
--- a/includes/queryprinters/SMW_QP_Table.php
+++ b/includes/queryprinters/SMW_QP_Table.php
@@ -2,10 +2,10 @@
 
 /**
  * Print query results in tables.
- * 
+ *
  * @author Markus Krötzsch
  * @author Jeroen De Dauw < [email protected] >
- * 
+ *
  * @file
  * @ingroup SMWQuery
  */
@@ -19,12 +19,15 @@
 
        protected function getResultText( SMWQueryResult $res, $outputmode ) {
                $result = '';
-               
+
+               $this->isHTML = ( $outputmode === SMW_OUTPUT_HTML );
+               $this->tableFormatter = new \SMW\TableFormatter( $this->isHTML 
);
+
                $columnClasses = array();
-               
+
                if ( $this->mShowHeaders != SMW_HEADERS_HIDE ) { // building 
headers
                        $headers = array();
-                       
+
                        foreach ( $res->getPrintRequests() as /* 
SMWPrintRequest */ $pr ) {
                                $attribs = array();
                                $columnClass = str_replace( array( ' ', '_' ), 
'-', strip_tags( $pr->getText( SMW_OUTPUT_WIKI ) ) );
@@ -33,71 +36,50 @@
                                // use in displaying each row.
                                $columnClasses[] = $columnClass;
                                $text = $pr->getText( $outputmode, ( 
$this->mShowHeaders == SMW_HEADERS_PLAIN ? null : $this->mLinker ) );
-                               
-                               $headers[] = Html::rawElement(
-                                       'th',
-                                       $attribs,
-                                       $text === '' ? '&nbsp;' : $text
-                               );
-                       }
-                       
-                       $headers = '<tr>' . implode( "\n", $headers ) . '</tr>';
-                       
-                       if ( $outputmode == SMW_OUTPUT_HTML ) {
-                               $headers = '<thead>' . $headers . '</thead>'; 
-                       }
-                       $headers = "\n$headers\n";
 
-                       $result .= $headers;
+                               $this->tableFormatter->addTableHeader( ( $text 
=== '' ? '&nbsp;' : $text ), $attribs );
+                       }
                }
-               
-               $tableRows = array();
-               $rowNum = 1;
+
                while ( $subject = $res->getNext() ) {
-                       $tableRows[] = $this->getRowForSubject( $subject, 
$outputmode, $columnClasses, $rowNum++ );
+                       $this->getRowForSubject( $subject, $outputmode, 
$columnClasses );
+                       $this->tableFormatter->addTableRow();
                }
 
-               $tableRows = implode( "\n", $tableRows );
-               
-               if ( $outputmode == SMW_OUTPUT_HTML ) {
-                       $tableRows = '<tbody>' . $tableRows . '</tbody>'; 
-               }
-               
-               $result .= $tableRows;
-               
                // print further results footer
                if ( $this->linkFurtherResults( $res ) ) {
                        $link = $this->getFurtherResultsLink( $res, $outputmode 
);
-                       $result .= "\t<tr class=\"smwfooter\"><td 
class=\"sortbottom\" colspan=\"" . $res->getColumnCount() . '"> ' . 
$link->getText( $outputmode, $this->mLinker ) . "</td></tr>\n";
+
+                       $this->tableFormatter->addTableCell(
+                                       $link->getText( $outputmode, 
$this->mLinker ),
+                                       array( 'class' => 'sortbottom', 
'colspan' => $res->getColumnCount() )
+                       );
+                       $this->tableFormatter->addTableRow( array( 'class' => 
'smwfooter' ) );
                }
-               
-               // Put the <table> tag around the whole thing
+
                $tableAttrs = array( 'class' => $this->params['class'] );
-               
+
                if ( $this->mFormat == 'broadtable' ) {
                        $tableAttrs['width'] = '100%';
                }
-               
-               $result = Xml::tags( 'table', $tableAttrs, $result );
 
-               $this->isHTML = ( $outputmode == SMW_OUTPUT_HTML ); // yes, our 
code can be viewed as HTML if requested, no more parsing needed
-               
-               return $result;
+               // @note A table is only transposable if header elements are 
visible
+               // $this->mShowHeaders !== SMW_HEADERS_HIDE && 
$this->params['transpose']
+               return $this->tableFormatter->transpose( false )->getTable( 
$tableAttrs );
        }
 
        /**
         * Gets a single table row for a subject, ie page.
-        * 
+        *
         * @since 1.6.1
-        * 
+        *
         * @param array $subject
         * @param $outputmode
-        * 
+        *
         * @return string
         */
-       protected function getRowForSubject( array /* of SMWResultArray */ 
$subject, $outputmode, $columnClasses, $rowNum ) {
-               $cells = array();
-               
+       protected function getRowForSubject( array /* of SMWResultArray */ 
$subject, $outputmode, $columnClasses ) {
+
                foreach ( $subject as $i => $field ) {
                        // $columnClasses will be empty if "headers=hide"
                        // was set.
@@ -106,43 +88,41 @@
                        } else {
                                $columnClass = null;
                        }
-                       $cells[] = $this->getCellForPropVals( $field, 
$outputmode, $columnClass );
+
+                       $this->getCellForPropVals( $field, $outputmode, 
$columnClass );
                }
-               
-               $rowClass = ( $rowNum % 2 == 1 ) ? 'row-odd' : 'row-even';
-               return "<tr class=\"$rowClass\">\n\t" . implode( "\n\t", $cells 
) . "\n</tr>";
        }
-       
+
        /**
         * Gets a table cell for all values of a property of a subject.
-        * 
+        *
         * @since 1.6.1
-        * 
+        *
         * @param SMWResultArray $resultArray
         * @param $outputmode
-        * 
+        *
         * @return string
         */
        protected function getCellForPropVals( SMWResultArray $resultArray, 
$outputmode, $columnClass ) {
                $dataValues = array();
-               
+
                while ( ( $dv = $resultArray->getNextDataValue() ) !== false ) {
                        $dataValues[] = $dv;
                }
-               
+
                $attribs = array();
                $content = null;
-               
+
                if ( count( $dataValues ) > 0 ) {
                        $sortkey = $dataValues[0]->getDataItem()->getSortKey();
                        $dataValueType = $dataValues[0]->getTypeID();
-                       
+
                        if ( is_numeric( $sortkey ) ) {
                                $attribs['data-sort-value'] = $sortkey;
                        }
-                       
+
                        $alignment = trim( 
$resultArray->getPrintRequest()->getParameter( 'align' ) );
-               
+
                        if ( in_array( $alignment, array( 'right', 'left', 
'center' ) ) ) {
                                $attribs['style'] = "text-align:' . $alignment 
. ';";
                        }
@@ -154,33 +134,29 @@
                                $resultArray->getPrintRequest()->getMode() == 
SMWPrintRequest::PRINT_THIS
                        );
                }
-               
-               return Html::rawElement(
-                       'td',
-                       $attribs,
-                       $content
-               );
+
+               $this->tableFormatter->addTableCell( $content, $attribs );
        }
-       
+
        /**
         * Gets the contents for a table cell for all values of a property of a 
subject.
-        * 
+        *
         * @since 1.6.1
-        * 
+        *
         * @param array $dataValues
         * @param $outputmode
         * @param boolean $isSubject
-        * 
+        *
         * @return string
         */
        protected function getCellContent( array /* of SMWDataValue */ 
$dataValues, $outputmode, $isSubject ) {
                $values = array();
-               
+
                foreach ( $dataValues as $dv ) {
                        $value = $dv->getShortText( $outputmode, 
$this->getLinker( $isSubject ) );
                        $values[] = $value;
                }
-               
+
                return implode( '<br />', $values );
        }
 
@@ -202,7 +178,13 @@
                        'default' => 'sortable wikitable smwtable',
                );
 
+               // Uncomment to enable this feature
+               // $params['transpose'] = array(
+               //      'type' => 'boolean',
+               //      'default' => false,
+               //      'message' => 'smw-paramdesc-table-transpose',
+               // );
+
                return $params;
        }
-       
 }
diff --git a/tests/phpunit/includes/formatters/TableFormatterTest.php 
b/tests/phpunit/includes/formatters/TableFormatterTest.php
new file mode 100644
index 0000000..df92097
--- /dev/null
+++ b/tests/phpunit/includes/formatters/TableFormatterTest.php
@@ -0,0 +1,377 @@
+<?php
+
+namespace SMW\Test;
+
+use SMW\TableFormatter;
+
+use ReflectionClass;
+
+/**
+ * Tests for the TableFormatter class
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.9
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @author mwjames
+ */
+
+/**
+ * @covers \SMW\TableFormatter
+ *
+ * @ingroup Test
+ *
+ * @group SMW
+ * @group SMWExtension
+ */
+class TableFormatterTest extends SemanticMediaWikiTestCase {
+
+       /**
+        * Returns the name of the class to be tested
+        *
+        * @return string|false
+        */
+       public function getClass() {
+               return '\SMW\TableFormatter';
+       }
+
+       /**
+        * Helper method that returns a TableFormatter object
+        *
+        * @since 1.9
+        *
+        * @param array $params
+        *
+        * @return TableFormatter
+        */
+       private function getInstance( $htmlContext = false ) {
+               return new TableFormatter( $htmlContext );
+       }
+
+       /**
+        * @test TableFormatter::__construct
+        *
+        * @since 1.9
+        */
+       public function testConstructor() {
+               $instance = $this->getInstance();
+               $this->assertInstanceOf( $this->getClass(), $instance );
+       }
+
+       /**
+        * @test TableFormatter::addHeaderItem
+        * @test TableFormatter::getHeaderItems
+        *
+        * @since 1.9
+        */
+       public function testAddHeaderItem() {
+               $instance = $this->getInstance();
+               $instance->addHeaderItem( 'span', 'lala' );
+
+               $matcher = array( 'tag' => 'span', 'content' => 'lala' );
+               $this->assertTag( $matcher, $instance->getHeaderItems() );
+       }
+
+       /**
+        * @test TableFormatter::addTableHeader
+        * @test TableFormatter::getTableHeader
+        *
+        * @since 1.9
+        */
+       public function testAddTableHeader() {
+
+               $instance = $this->getInstance();
+               $instance->addTableHeader( 'lala' );
+               $instance->getTable();
+
+               // Access protected method
+               $reflection = new ReflectionClass( $this->getClass() );
+               $method = $reflection->getMethod( 'getTableHeader' );
+               $method->setAccessible( true );
+
+               $matcher = array( 'tag' => 'th', 'content' => 'lala' );
+               $this->assertTag( $matcher, $method->invoke( $instance ) );
+
+               // HTML context
+               $instance = $this->getInstance( true );
+               $instance->addTableHeader( 'lila' );
+               $instance->getTable();
+
+               // Access protected method
+               $reflection = new ReflectionClass( $this->getClass() );
+               $method = $reflection->getMethod( 'getTableHeader' );
+               $method->setAccessible( true );
+
+               $matcher = array(
+                       'tag' => 'thead',
+                       'child' => array(
+                               'tag' => 'th',
+                               'content' => 'lila'
+                       )
+               );
+
+               $this->assertTag( $matcher, $method->invoke( $instance ) );
+
+       }
+
+       /**
+        * @test TableFormatter::addTableRow
+        * @test TableFormatter::addTableCell
+        *
+        * @since 1.9
+        */
+       public function testAddTableRow() {
+
+               $instance = $this->getInstance();
+               $instance->addTableCell( 'lala', array( 'class' => 'foo' ) )
+                       ->addTableRow()
+                       ->addTableCell( 'lula' )
+                       ->addTableRow()
+                       ->getTable();
+
+               // Access protected method
+               $reflection = new ReflectionClass( $this->getClass() );
+               $method = $reflection->getMethod( 'getTableRows' );
+               $method->setAccessible( true );
+
+               $matcher = array(
+                       'tag' => 'tr',
+                       'attributes' => array( 'class' => 'foo row-odd' ),
+                       'attributes' => array( 'class' => 'row-even' ),
+                       'descendant' => array(
+                               'tag' => 'td',
+                               'content' => 'lala'
+                       ),
+                       'descendant' => array(
+                               'tag' => 'td',
+                               'content' => 'lula'
+                       )
+               );
+
+               $this->assertTag( $matcher, $method->invoke( $instance ) );
+
+               // HTML context
+               $instance = $this->getInstance( true );
+               $instance->addTableCell( 'lila' )->addTableRow()->getTable();
+
+               // Access protected method
+               $reflection = new ReflectionClass( $this->getClass() );
+               $method = $reflection->getMethod( 'getTableRows' );
+               $method->setAccessible( true );
+
+               $matcher = array(
+                       'tag' => 'tbody',
+                       'descendant' => array(
+                               'tag' => 'tr',
+                               'attributes' => array(
+                                       'class' => 'row-odd'
+                               ),
+                               'child' => array(
+                                       'tag' => 'td',
+                                       'content' => 'lila'
+                               ),
+                       )
+               );
+
+               $this->assertTag( $matcher, $method->invoke( $instance ) );
+
+       }
+
+       /**
+        * @test TableFormatter::getTable
+        *
+        * @since 1.9
+        */
+       public function testStandardTable() {
+
+               $instance = $this->getInstance();
+
+               // Row + cell
+               $instance->addTableCell( 'lala', array( 'rel' => 'tuuu' ) )
+                       ->addTableRow( array( 'class' => 'foo' ) );
+
+               $matcher = array(
+                       'tag' => 'table',
+                       'descendant' => array(
+                               'tag' => 'tr',
+                               'attributes' => array( 'class' => 'foo row-odd' 
),
+                               'child' => array(
+                                       'tag' => 'td',
+                                       'content' => 'lala',
+                                       'attributes' => array( 'rel' => 'tuuu' )
+                               )
+                       )
+               );
+
+               $this->assertTag( $matcher, $instance->getTable() );
+
+               // Head + row + cell
+               $instance = $this->getInstance();
+               $instance->addTableHeader( 'lula' )
+                       ->addTableCell( 'lala' )
+                       ->addTableRow();
+
+               $matcher = array(
+                       'tag' => 'table',
+                       'descendant' => array(
+                               'tag' => 'th',
+                               'child' => array( 'tag' => 'td', 'content' => 
'lula' ),
+                       ),
+                       'descendant' => array(
+                               'tag' => 'tr',
+                               'attributes' => array( 'class' => 'row-odd' ),
+                               'child' => array( 'tag' => 'td', 'content' => 
'lala' ),
+                       )
+               );
+
+               $this->assertTag( $matcher, $instance->getTable() );
+
+               // HTML context
+               $instance = $this->getInstance( true );
+               $instance->addTableHeader( 'lula' )
+                       ->addTableCell( 'lala' )
+                       ->addTableRow();
+
+               // Doing a lazy check here ...
+               $matcher = array(
+                       'tag' => 'table',
+                       'descendant' => array(
+                               'tag' => 'thead',
+                               'child' => array( 'content' => 'lula' )
+                       ),
+                       'descendant' => array(
+                               'tag' => 'tbody',
+                               'child' => array( 'content' => 'lala' )
+                       ),
+               );
+
+               $this->assertTag( $matcher, $instance->getTable() );
+       }
+
+       /**
+        * @test TableFormatter::getTable
+        *
+        * @since 1.9
+        */
+       public function testEmptyTable() {
+               $instance = $this->getInstance();
+               $instance->addTableCell()->addTableRow();
+               $this->assertEmpty( $instance->getTable() );
+       }
+
+       /**
+        * @test TableFormatter::getTable
+        * @test TableFormatter::transpose
+        *
+        * @since 1.9
+        */
+       public function testTransposedTable() {
+
+               $instance = $this->getInstance();
+
+               // We need a dedicated header definition to support a table 
transpose
+               $instance->addTableHeader( 'Foo' )->addTableHeader( 'Bar' )
+                       ->addTableCell( 'lala', array( 'class' => 'foo' ) )
+                       ->addTableRow()
+                       ->addTableCell( 'lula', array( 'rel' => 'tuuu' ) 
)->addTableCell( 'lila' )
+                       ->addTableRow();
+
+               $matcher = array(
+                       'tag' => 'tr',
+                       'attributes' => array( 'class' => 'row-odd' ),
+                       'child' => array(
+                               'tag' => 'th',
+                               'content' => 'Foo'
+                       ),
+                       'descendant' => array(
+                               'tag' => 'td',
+                               'content' => 'lala',
+                               'attributes' => array( 'class' => 'foo' ),
+                       ),
+                       'descendant' => array(
+                               'tag' => 'td',
+                               'content' => 'lula',
+                               'attributes' => array( 'rel' => 'tuuu' )
+                       ),
+                       'tag' => 'tr',
+                       'attributes' => array( 'class' => 'row-even' ),
+                       'child' => array(
+                               'tag' => 'th',
+                               'content' => 'Bar'
+                       ),
+                       'descendant' => array(
+                               'tag' => 'td',
+                               'content' => ''
+                       ),
+                       'descendant' => array(
+                               'tag' => 'td',
+                               'content' => 'lila'
+                       ),
+               );
+
+               $this->assertTag( $matcher, $instance->transpose( true 
)->getTable() );
+
+               // HTML context
+               $instance = $this->getInstance( true );
+               $instance->addTableHeader( 'Foo' )->addTableHeader( 'Bar' )
+                       ->addTableCell( 'lala', array( 'class' => 'foo' ) )
+                       ->addTableRow()
+                       ->addTableCell( 'lula' )->addTableCell( 'lila' )
+                       ->addTableRow();
+
+               $matcher = array(
+                       'tag' => 'thead',
+                       'tag' => 'tbody',
+                       'child' => array(
+                               'tag' => 'tr',
+                               'attributes' => array( 'class' => 'row-odd' ),
+                               'child' => array(
+                                       'tag' => 'th',
+                                       'content' => 'Foo'
+                               ),
+                               'descendant' => array(
+                                       'tag' => 'td',
+                                       'content' => 'lala',
+                                       'attributes' => array( 'class' => 'foo' 
),
+                               ),
+                               'descendant' => array(
+                                       'tag' => 'td',
+                                       'content' => 'lula'
+                               ),
+                               'tag' => 'tr',
+                               'attributes' => array( 'class' => 'row-even' ),
+                               'child' => array(
+                                       'tag' => 'th',
+                                       'content' => 'Bar'
+                               ),
+                               'descendant' => array(
+                                       'tag' => 'td',
+                                       'content' => ''
+                               ),
+                               'descendant' => array(
+                                       'tag' => 'td',
+                                       'content' => 'lila'
+                               ),
+                       )
+               );
+
+               $this->assertTag( $matcher, $instance->transpose( true 
)->getTable() );
+
+       }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/66537
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I11c0057669e0a18c7b573ef64b21414fcb202b01
Gerrit-PatchSet: 8
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: Mwjames <[email protected]>
Gerrit-Reviewer: Netbrain <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to