<?php
/**
 * FIT Fixture: Summary
 * 
 * $Id$
 * 
 * @author gERD Schaufelberger <gerd@php-tools.net>
 * @author Daniel Jahnke <jahnke.daniel@web.de>
 * @package FIT
 * @subpackage Fixture
 * @license LGPL http://www.gnu.org/copyleft/lesser.html
 */

/**
 * FIT Fixture: Summary
 * 
 * Summery fixture summs up the results of the tables. Hence it is not
 * a table holding test data but a place to put results.
 *
 * @version 0.1.1
 * @package FIT
 * @subpackage Fixture
 */
class PHPFIT_Fixture_Summary extends PHPFIT_Fixture 
{

   
/**
    * summary of tables
    * @var array
    */
    
private $_summary;

   
/**
    * number of rows
    * @var int
    */
    
private $_rows;

   
/**
    * number of cols
    * @var int
    */
    
private $_cols;
    
   
/**
    * parser object
    * @var object
    */
    
private $_parser;

   
/**
    * integer-object to validate cell-values
    * @var object
    */
    
private $_integer;

   
/**
    * actual summary
    * @var int
    */
    
private static $_actualSummary 0;

   
/**
    * before summary
    * @var int
    */
    
private static $_beforeSummary 0;

   
/**
    * node
    * @var object 
    */
    
private $_node;

   
/**
    * resultMarks contain the right, wrong, ... values
    * @var array
    */
    
private $_resultMarks;

   
/**
    * constructor
    *
    * creates neede type-filter to validate cell-values
    */
    
public function __construct()
    {
        
$this->_integer PHPFIT_TypeFilter::create'Integer' );
    }

   
/**
    * iterate through table 
    * 
    * @param object $node
    * @return boolean true on success
    * @see doRows()
    */
    
public function doRowsPHPFIT_Node $node )
    {
        
$this->_node    $node;
        
$this->_summary $node->getSummary();
        
$this->_parser  $node->getParser();

        
$this->_tableCount          $this->_summary->countChildNodes() - 1;

        for( 
$i 0$i <= $this->_tableCount$i++ ) {
            
$tableName $this->_summary->getNodeValue'attributes'$i0);
            if( !
$tableName['noSummary']  && ( $i self::$_actualSummary ) ) {
                
self::$_beforeSummary self::$_actualSummary;
                
self::$_actualSummary $i;
                break;
            }
        }

        
$this-> _buildSummaryTable();

        
$beginTest 0;
        
$endTest   0;

        
$this->_resultMarks $this->_createSummary$beginTest$endTest );

        
$i 0;
        foreach( 
$this->_resultMarks as $key =>  $value ) {
            
// set right wrong ignore exception headeline
            
$this->_parser->setNodeValue'cData'$keyself::$_actualSummary1, ++$i );
            
// set values 
            
$this->_parser->setNodeValue'cData'$this->_integer->out$value ), self::$_actualSummary2$i );
        }

        
// set elapsed time
        
$duration $endTest $beginTest;
        
$this->_parser->setNodeValue'cData'$duration ' sec'self::$_actualSummary3);

        
// set date
        
$dateStr date'd.m.Y' ) . '&nbsp;&nbsp;' date'H:i:s' ) . ' time';
        
$this->_parser->setNodeValue'cData'$dateStrself::$_actualSummary4);

        if( !
$this->doRow$this->_node ) ) {
            return 
false;
        }

        return 
true;
    }

   
/**
    * process cells
    *
    * Generic processing of all upcoming cells. Actually, this method
    * just iterates through them and mark the cells on summary dependency
    * 
    * @param object $node 
    * @return boolean true on success
    */
    
public function doCellsPHPFIT_Node $node 
    {
        
// jump over first two rows
        
$this->_node->next();
        
$this->_node->next();

        
$cells  $node->getRowIterator();
        foreach( 
$cells as $no => $cdata ) {
            
// to jump over description row
            
if( $no == ) {
                continue;
            }

            switch( 
$no ) {
                case 
1// right cell
                    
$cdata $cells->mark'right' ) : $cells->mark'wrong'$cdata );
                    break;
                case 
2// wrong cell
                    
$cdata == $cells->mark'right' ) : $cells->mark'wrong' );
                    break;
                case 
3// error cell
                    
$cdata == $cells->mark'right' ) : $cells->mark'error' );
                    break;
                case 
4// ignore cell
                    
$cdata == $cells->mark'right' ) : $cells->mark'ignore' );
                    break;
                case 
5:
                    
$cdata == $cells->mark'right' ) : $cells->mark'exception' );
                    break;
                default:
                    return 
false;
            }
        }

        return 
true;
    }

   
/**
    * create summary
    *
    * walk through the tables and count the wrong,
    * right, ignore and exceptions
    * 
    * @return array resultMarks     result of counting the testresult
    */
    
private function _createSummary( &$beginTest, &$endTest )
    {
        
$resultMarks = array( 
                        
'right'      => 0,
                        
'wrong'      => 0,
                        
'error'      => 0,
                        
'ignore'     => 0,
                        
'exception'  => 0,
                        
'time'       => 0
                            
);

        for( 
$table self::$_beforeSummary $table self::$_actualSummary$table++ ) {

            
// if fit summary then conitune
            
$attrib $this->_summary->getNodeValue'attributes'$table0);
            if( !isset( 
$attrib['noSummary'] ) && empty( $attrib['noSummary'] ) ) {
                continue;
            }

            
$this->_rows     $this->_summary->countChildNodes$table );
            
$this->_cols     $this->_summary->countChildNodes$table$this->_rows-);

            for( 
$row 0$row $this->_rows$row++ ) {
                for( 
$col 0$col $this->_cols$col++ ) {
                    
$att $this->_summary->getNodeValue'attributes'$table$row$col );
                    if( !isset( 
$att['results'] ) ) {
                        continue;
                    }

                    
$result =   $att['results'];

                    if( isset( 
$result['time']['funcStart'] ) && $beginTest == ) {
                        
$beginTest $result['time']['funcStart'];
                    }

                    if( isset( 
$result['time']['funcEnd'] ) ) {
                        
$endTest $result['time']['funcEnd'];
                    }

                    ++
$resultMarks[$result['type']];
                }
            }
        }

        return 
$resultMarks;
    }

   
/**
    * build summary table
    *
    * append five columns
    * append rows
    * - headline for testresult     <strong>right</strong>, <strong>wrong</strong>, <strong>ignore</strong>, <strong>error</strong>, <strong>exception</strong>
    * - count                       number of test that faild, right ...
    * - elapsed time                duration of test
    * - date                        date and time
    * @return void
    */
    
private function _buildSummaryTable()
    {
        
$rows $this->_summary->countChildNodesself::$_actualSummary ) - 1;
        
$cols $this->_summary->countChildNodesself::$_actualSummary$rows );

        
// delete rows
        
while( $this->_parser->countChildNodesself::$_actualSummary ) > ) {
            
$this->_parser->deleteRowself::$_actualSummary);
        }
        
        
// delete cols
        
while( $this->_parser->countChildNodesself::$_actualSummary) > ) {
            
$this->_parser->deleteBeforeColumnself::$_actualSummary0);
        }

        
// four rows are required, each having five columns
        
$this->_parser->appendRowself::$_actualSummary );
        
$this->_parser->appendRowself::$_actualSummary );
        
// set count
        
$this->_parser->setNodeValue'cData''count'self::$_actualSummary2);

        
// append 2 rows
        
for( $i 0$i 2$i++ ) {
            
$this->_parser->appendRowself::$_actualSummary );
        }

        
// append 5 cols
        
for( $i 0$i 5$i++ ) {
            
$this->_parser->appendColumnself::$_actualSummary );
        }

        
$this->_parser->setNodeValue'cData''elapsed time'self::$_actualSummary3);
        
$this->_parser->setNodeValue'cData''date'self::$_actualSummary4);
        
        for( 
$i 6$i 2; --$i ) {
            
$this->_parser->deleteBeforeColumnself::$_actualSummary3$i );
            
$this->_parser->deleteBeforeColumnself::$_actualSummary4$i );
        }
        
        
$this->_parser->setNodeValue'attributes', array( 'colspan' => '5' ), self::$_actualSummary3);
        
$this->_parser->setNodeValue'attributes', array( 'colspan' => '5' ), self::$_actualSummary4);
    }
}
?>