<?php
/**
 * FIT Fixture: ActionFixture
 * 
 * $Id$
 * 
 * @author gERD Schaufelberger <gerd@php-tools.net>
 * @package FIT
 * @subpackage Fixture
 * @license LGPL http://www.gnu.org/copyleft/lesser.html
 */

/**
 * FIT Fixture: ActionFixture
 * 
 * An action fixture interprets rows as a sequence of commands to be performed 
 * in order. It interprets tables for which the first column contains one of a
 * small number of commands. Subsequent columns contain values interpreted by 
 * the particular command. The generic action fixture offers only four commands, 
 * but subclasses may extend this set.
 * 
 * @version 0.1.0
 * @package FIT
 * @subpackage Fixture
 */
class Testing_FIT_Fixture_Action extends Testing_FIT_Fixture 
{
   
/**
    * column iterator
    * @var object
    */
    
protected $_cells;

   
/**
    * actor that has been startet
    * 
    * The actor is static to make HTML tables "interuptable"
    * This way a table may end, another start and you are still at the same 
    * fixture.
    * 
    * @var Fixture
    * @see start()
    * @todo is static actors the intended behavior?
    */
    
protected static $actor null;
    
   
/**
    * Implements start fixture 
    * 
    * Start aClass - Subsequent commands are directed to an instance of 
    * aClass. This is similar to navigating to a particular GUI screen.
    * 
    * @return void
    */       
    
public function start() 
    {
        
$this->_cells->next();
        
$aClass         $this->_cells->current();
        
self::$actor    Testing_FIT_Fixture::loadFixture$aClass );
    }
    
   
/**
    * Implements enter fixture 
    * 
    * Enter aMethod anArgument - Invoke aMethod with anArgument (of type 
    * determined by aMethod.) This is similar to entering values into GUI fields.
    * 
    * @return void
    */       
    
public function enter() 
    {
        
$this->_cells->next();
        
$aMethod    $this->camel$this->_cells->current() );
        
        
$this->_cells->next();
        
$anArgument $this->_cells->current();
        
        
self::$actor->$aMethod$anArgument );
    }
    
   
/**
    * Implements press fixture 
    * 
    * Press aMethod - Invoke aMethod with no arguments. This is 
    * similar to pressing a GUI button.
    * 
    * @return void
    */       
    
public function press() 
    {
        
$this->_cells->next();
        
$aMethod    $this->camel$this->_cells->current() );
        
        
self::$actor->$aMethod();
    }

   
/**
    * Implements check fixture 
    * 
    * Check aMethod aValue - Invoke aMethod with no arguments. 
    * Compare the returned value with aValue. This is similar to reading 
    * values from a GUI screen.
    * 
    * @return void
    */       
    
public function check() 
    {
        
$this->_cells->next();
        
$aMethod    $this->camel$this->_cells->current() );
        
        
$result     self::$actor->$aMethod();
        
        
$this->_cells->next();
        
$this->_checkCell$this->_cells$result );
    }
    
   
/**
    * process cells
    *
    * In case of ActionFixture each row has to be interpreted as a command
    * Processing cells means to execute one command. 
    *
    * An action fixture interprets tables for which the first column contains 
    * one of a small number of commands. Subsequent columns contain values 
    * interpreted by the particular command. The generic action fixture offers 
    * only four commands, but subclasses may extend this set.
    * 
    * @param object $node
    * @return boole true on success
    */
    
public function doCellsTesting_FIT_Node $node 
    {
        
$this->_cells  $node->getRowIterator();
        
        
// first cell is the method to be called
        
$method  $this->_cells->current();
        
        try{ 
            if( !
method_exists$this$method ) ) {
                throw new 
Exception'Action fixture cannot call the request command. Method ' 
                    
get_class$this ) . '->' $method ' does not exist' );
            }
            
$this->$method();            
        } 
        catch( 
Exception $e ) {
            
$this->_cells->markException$e );
        }
        
        
$this->_cells->next();
        return 
true;
    }
}
?>