Source for file mock_objects.php

Documentation is available at mock_objects.php

  1. <?php
  2. /**
  3.  *  base include file for SimpleTest
  4.  *  @package    SimpleTest
  5.  *  @subpackage MockObjects
  6.  *  @version    $Id: mock_objects.php 1672 2008-03-02 04:47:34Z edwardzyang $
  7.  */
  8.  
  9. /**#@+
  10.  * include SimpleTest files
  11.  */
  12. require_once(dirname(__FILE__'/expectation.php');
  13. require_once(dirname(__FILE__'/simpletest.php');
  14. require_once(dirname(__FILE__'/dumper.php');
  15. if (version_compare(phpversion()'5'>= 0{
  16.     require_once(dirname(__FILE__'/reflection_php5.php');
  17. else {
  18.     require_once(dirname(__FILE__'/reflection_php4.php');
  19. }
  20. /**#@-*/
  21.  
  22.  * Default character simpletest will substitute for any value
  23.  */
  24. if (defined('MOCK_ANYTHING')) {
  25.     define('MOCK_ANYTHING''*');
  26. }
  27.  
  28. /**
  29.  *    Parameter comparison assertion.
  30.  *    @package SimpleTest
  31.  *    @subpackage MockObjects
  32.  */
  33.     var $_expected;
  34.  
  35.     /**
  36.      *    Sets the expected parameter list.
  37.      *    @param array $parameters  Array of parameters including
  38.      *                               those that are wildcarded.
  39.      *                               If the value is not an array
  40.      *                               then it is considered to match any.
  41.      *    @param string $message    Customised message on failure.
  42.      *    @access public
  43.      */
  44.     function ParametersExpectation($expected false$message '%s'{
  45.         $this->SimpleExpectation($message);
  46.         $this->_expected = $expected;
  47.     }
  48.  
  49.     /**
  50.      *    Tests the assertion. True if correct.
  51.      *    @param array $parameters     Comparison values.
  52.      *    @return boolean              True if correct.
  53.      *    @access public
  54.      */
  55.     function test($parameters{
  56.         if (is_array($this->_expected)) {
  57.             return true;
  58.         }
  59.         if (count($this->_expected!= count($parameters)) {
  60.             return false;
  61.         }
  62.         for ($i 0$i count($this->_expected)$i++{
  63.             if ($this->_testParameter($parameters[$i]$this->_expected[$i])) {
  64.                 return false;
  65.             }
  66.         }
  67.         return true;
  68.     }
  69.  
  70.     /**
  71.      *    Tests an individual parameter.
  72.      *    @param mixed $parameter    Value to test.
  73.      *    @param mixed $expected     Comparison value.
  74.      *    @return boolean            True if expectation
  75.      *                                fulfilled.
  76.      *    @access private
  77.      */
  78.     function _testParameter($parameter$expected{
  79.         $comparison $this->_coerceToExpectation($expected);
  80.         return $comparison->test($parameter);
  81.     }
  82.  
  83.     /**
  84.      *    Returns a human readable test message.
  85.      *    @param array $comparison   Incoming parameter list.
  86.      *    @return string             Description of success
  87.      *                                or failure.
  88.      *    @access public
  89.      */
  90.     function testMessage($parameters{
  91.         if ($this->test($parameters)) {
  92.             return "Expectation of " count($this->_expected.
  93.                     " arguments of [" $this->_renderArguments($this->_expected.
  94.                     "] is correct";
  95.         else {
  96.             return $this->_describeDifference($this->_expected$parameters);
  97.         }
  98.     }
  99.  
  100.     /**
  101.      *    Message to display if expectation differs from
  102.      *    the parameters actually received.
  103.      *    @param array $expected      Expected parameters as list.
  104.      *    @param array $parameters    Actual parameters received.
  105.      *    @return string              Description of difference.
  106.      *    @access private
  107.      */
  108.     function _describeDifference($expected$parameters{
  109.         if (count($expected!= count($parameters)) {
  110.             return "Expected " count($expected.
  111.                     " arguments of [" $this->_renderArguments($expected.
  112.                     "] but got " count($parameters.
  113.                     " arguments of [" $this->_renderArguments($parameters"]";
  114.         }
  115.         $messages array();
  116.         for ($i 0$i count($expected)$i++{
  117.             $comparison $this->_coerceToExpectation($expected[$i]);
  118.             if ($comparison->test($parameters[$i])) {
  119.                 $messages["parameter " ($i 1" with [" .
  120.                         $comparison->overlayMessage($parameters[$i]$this->_getDumper()) "]";
  121.             }
  122.         }
  123.         return "Parameter expectation differs at " implode(" and "$messages);
  124.     }
  125.  
  126.     /**
  127.      *    Creates an identical expectation if the
  128.      *    object/value is not already some type
  129.      *    of expectation.
  130.      *    @param mixed $expected      Expected value.
  131.      *    @return SimpleExpectation   Expectation object.
  132.      *    @access private
  133.      */
  134.     function _coerceToExpectation($expected{
  135.         if (SimpleExpectation::isExpectation($expected)) {
  136.             return $expected;
  137.         }
  138.         return new IdenticalExpectation($expected);
  139.     }
  140.  
  141.     /**
  142.      *    Renders the argument list as a string for
  143.      *    messages.
  144.      *    @param array $args    Incoming arguments.
  145.      *    @return string        Simple description of type and value.
  146.      *    @access private
  147.      */
  148.     function _renderArguments($args{
  149.         $descriptions array();
  150.         if (is_array($args)) {
  151.             foreach ($args as $arg{
  152.                 $dumper &new SimpleDumper();
  153.                 $descriptions[$dumper->describeValue($arg);
  154.             }
  155.         }
  156.         return implode(', '$descriptions);
  157.     }
  158. }
  159.  
  160. /**
  161.  *    Confirms that the number of calls on a method is as expected.
  162.  *  @package    SimpleTest
  163.  *  @subpackage MockObjects
  164.  */
  165.     var $_method;
  166.     var $_count;
  167.  
  168.     /**
  169.      *    Stashes the method and expected count for later
  170.      *    reporting.
  171.      *    @param string $method    Name of method to confirm against.
  172.      *    @param integer $count    Expected number of calls.
  173.      *    @param string $message   Custom error message.
  174.      */
  175.     function CallCountExpectation($method$count$message '%s'{
  176.         $this->_method = $method;
  177.         $this->_count = $count;
  178.         $this->SimpleExpectation($message);
  179.     }
  180.  
  181.     /**
  182.      *    Tests the assertion. True if correct.
  183.      *    @param integer $compare     Measured call count.
  184.      *    @return boolean             True if expected.
  185.      *    @access public
  186.      */
  187.     function test($compare{
  188.         return ($this->_count == $compare);
  189.     }
  190.  
  191.     /**
  192.      *    Reports the comparison.
  193.      *    @param integer $compare     Measured call count.
  194.      *    @return string              Message to show.
  195.      *    @access public
  196.      */
  197.     function testMessage($compare{
  198.         return 'Expected call count for [' $this->_method .
  199.                 '] was [' $this->_count .
  200.                 '] got [' $compare ']';
  201.     }
  202. }
  203.  
  204. /**
  205.  *    Confirms that the number of calls on a method is as expected.
  206.  *  @package    SimpleTest
  207.  *  @subpackage MockObjects
  208.  */
  209.     var $_method;
  210.     var $_count;
  211.  
  212.     /**
  213.      *    Stashes the method and expected count for later
  214.      *    reporting.
  215.      *    @param string $method    Name of method to confirm against.
  216.      *    @param integer $count    Minimum number of calls.
  217.      *    @param string $message   Custom error message.
  218.      */
  219.     function MinimumCallCountExpectation($method$count$message '%s'{
  220.         $this->_method = $method;
  221.         $this->_count = $count;
  222.         $this->SimpleExpectation($message);
  223.     }
  224.  
  225.     /**
  226.      *    Tests the assertion. True if correct.
  227.      *    @param integer $compare     Measured call count.
  228.      *    @return boolean             True if enough.
  229.      *    @access public
  230.      */
  231.     function test($compare{
  232.         return ($this->_count <= $compare);
  233.     }
  234.  
  235.     /**
  236.      *    Reports the comparison.
  237.      *    @param integer $compare     Measured call count.
  238.      *    @return string              Message to show.
  239.      *    @access public
  240.      */
  241.     function testMessage($compare{
  242.         return 'Minimum call count for [' $this->_method .
  243.                 '] was [' $this->_count .
  244.                 '] got [' $compare ']';
  245.     }
  246. }
  247.  
  248. /**
  249.  *    Confirms that the number of calls on a method is as expected.
  250.  *    @package      SimpleTest
  251.  *    @subpackage   MockObjects
  252.  */
  253.     var $_method;
  254.     var $_count;
  255.  
  256.     /**
  257.      *    Stashes the method and expected count for later
  258.      *    reporting.
  259.      *    @param string $method    Name of method to confirm against.
  260.      *    @param integer $count    Minimum number of calls.
  261.      *    @param string $message   Custom error message.
  262.      */
  263.     function MaximumCallCountExpectation($method$count$message '%s'{
  264.         $this->_method = $method;
  265.         $this->_count = $count;
  266.         $this->SimpleExpectation($message);
  267.     }
  268.  
  269.     /**
  270.      *    Tests the assertion. True if correct.
  271.      *    @param integer $compare     Measured call count.
  272.      *    @return boolean             True if not over.
  273.      *    @access public
  274.      */
  275.     function test($compare{
  276.         return ($this->_count >= $compare);
  277.     }
  278.  
  279.     /**
  280.      *    Reports the comparison.
  281.      *    @param integer $compare     Measured call count.
  282.      *    @return string              Message to show.
  283.      *    @access public
  284.      */
  285.     function testMessage($compare{
  286.         return 'Maximum call count for [' $this->_method .
  287.                 '] was [' $this->_count .
  288.                 '] got [' $compare ']';
  289.     }
  290. }
  291.  
  292. /**
  293.  *    Retrieves method actions by searching the
  294.  *    parameter lists until an expected match is found.
  295.  *    @package SimpleTest
  296.  *    @subpackage MockObjects
  297.  */
  298.     var $_map;
  299.  
  300.     /**
  301.      *    Creates an empty call map.
  302.      *    @access public
  303.      */
  304.     function SimpleSignatureMap({
  305.         $this->_map = array();
  306.     }
  307.  
  308.     /**
  309.      *    Stashes a reference against a method call.
  310.      *    @param array $parameters    Array of arguments (including wildcards).
  311.      *    @param mixed $action        Reference placed in the map.
  312.      *    @access public
  313.      */
  314.     function add($parameters&$action{
  315.         $place count($this->_map);
  316.         $this->_map[$placearray();
  317.         $this->_map[$place]['params'new ParametersExpectation($parameters);
  318.         $this->_map[$place]['content'&$action;
  319.     }
  320.  
  321.     /**
  322.      *    Searches the call list for a matching parameter
  323.      *    set. Returned by reference.
  324.      *    @param array $parameters    Parameters to search by
  325.      *                                 without wildcards.
  326.      *    @return object              Object held in the first matching
  327.      *                                 slot, otherwise null.
  328.      *    @access public
  329.      */
  330.     function &findFirstAction($parameters{
  331.         $slot $this->_findFirstSlot($parameters);
  332.         if (isset($slot&& isset($slot['content'])) {
  333.             return $slot['content'];
  334.         }
  335.         $null null;
  336.         return $null;
  337.     }
  338.  
  339.     /**
  340.      *    Searches the call list for a matching parameter
  341.      *    set. True if successful.
  342.      *    @param array $parameters    Parameters to search by
  343.      *                                 without wildcards.
  344.      *    @return boolean             True if a match is present.
  345.      *    @access public
  346.      */
  347.     function isMatch($parameters{
  348.         return ($this->_findFirstSlot($parameters!= null);
  349.     }
  350.     
  351.     /**
  352.      *    Compares the incoming parameters with the
  353.      *    internal expectation. Uses the incoming $test
  354.      *    to dispatch the test message.
  355.      *    @param SimpleTestCase $test   Test to dispatch to.
  356.      *    @param array $parameters      The actual calling arguments.
  357.      *    @param string $message        The message to overlay.
  358.      *    @access public
  359.      */
  360.     function test(&$test$parameters$message{
  361.     }
  362.  
  363.     /**
  364.      *    Searches the map for a matching item.
  365.      *    @param array $parameters    Parameters to search by
  366.      *                                 without wildcards.
  367.      *    @return array               Reference to slot or null.
  368.      *    @access private
  369.      */
  370.     function &_findFirstSlot($parameters{
  371.         $count count($this->_map);
  372.         for ($i 0$i $count$i++{
  373.             if ($this->_map[$i]["params"]->test($parameters)) {
  374.                 return $this->_map[$i];
  375.             }
  376.         }
  377.         $null null;
  378.         return $null;
  379.     }
  380. }
  381.  
  382. /**
  383.  *    Allows setting of actions against call signatures either
  384.  *    at a specific time, or always. Specific time settings
  385.  *    trump lasting ones, otherwise the most recently added
  386.  *    will mask an earlier match.
  387.  *    @package SimpleTest
  388.  *    @subpackage MockObjects
  389.  */
  390.     var $_wildcard = MOCK_ANYTHING;
  391.     var $_always;
  392.     var $_at;
  393.     
  394.     /**
  395.      *    Sets up an empty response schedule.
  396.      *    Creates an empty call map.
  397.      */
  398.     function SimpleCallSchedule({
  399.         $this->_always = array();
  400.         $this->_at = array();
  401.     }
  402.     
  403.     /**
  404.      *    Stores an action against a signature that
  405.      *    will always fire unless masked by a time
  406.      *    specific one.
  407.      *    @param string $method        Method name.
  408.      *    @param array $args           Calling parameters.
  409.      *    @param SimpleAction $action  Actually simpleByValue, etc.
  410.      *    @access public
  411.      */
  412.     function register($method$args&$action{
  413.         $args $this->_replaceWildcards($args);
  414.         $method strtolower($method);
  415.         if (isset($this->_always[$method])) {
  416.             $this->_always[$methodnew SimpleSignatureMap();
  417.         }
  418.         $this->_always[$method]->add($args$action);
  419.     }
  420.     
  421.     /**
  422.      *    Stores an action against a signature that
  423.      *    will fire at a specific time in the future.
  424.      *    @param integer $step         delay of calls to this method,
  425.      *                                  0 is next.
  426.      *    @param string $method        Method name.
  427.      *    @param array $args           Calling parameters.
  428.      *    @param SimpleAction $action  Actually SimpleByValue, etc.
  429.      *    @access public
  430.      */
  431.     function registerAt($step$method$args&$action{
  432.         $args $this->_replaceWildcards($args);
  433.         $method strtolower($method);
  434.         if (isset($this->_at[$method])) {
  435.             $this->_at[$methodarray();
  436.         }
  437.         if (isset($this->_at[$method][$step])) {
  438.             $this->_at[$method][$stepnew SimpleSignatureMap();
  439.         }
  440.         $this->_at[$method][$step]->add($args$action);
  441.     }
  442.     
  443.     function expectArguments($method$args$message{
  444.         $args $this->_replaceWildcards($args);
  445.         $message .= Mock::getExpectationLine();
  446.         $this->_expected_args[strtolower($method)=
  447.                 new ParametersExpectation($args$message);
  448.  
  449.     }
  450.     
  451.     /**
  452.      *    Actually carry out the action stored previously,
  453.      *    if the parameters match.
  454.      *    @param integer $step      Time of call.
  455.      *    @param string $method     Method name.
  456.      *    @param array $args        The parameters making up the
  457.      *                               rest of the call.
  458.      *    @return mixed             The result of the action.
  459.      *    @access public.
  460.      */
  461.     function &respond($step$method$args{
  462.         $method strtolower($method);
  463.         if (isset($this->_at[$method][$step])) {
  464.             if ($this->_at[$method][$step]->isMatch($args)) {
  465.                 $action &$this->_at[$method][$step]->findFirstAction($args);
  466.                 if (isset($action)) {
  467.                     return $action->act();
  468.                 }
  469.             }
  470.         }
  471.         if (isset($this->_always[$method])) {
  472.             $action &$this->_always[$method]->findFirstAction($args);
  473.             if (isset($action)) {
  474.                 return $action->act();
  475.             }
  476.         }
  477.         $null null;
  478.         return $null;
  479.     }
  480.     
  481.     /**
  482.      *    Replaces wildcard matches with wildcard
  483.      *    expectations in the argument list.
  484.      *    @param array $args      Raw argument list.
  485.      *    @return array           Argument list with
  486.      *                             expectations.
  487.      *    @access private
  488.      */
  489.     function _replaceWildcards($args{
  490.         if ($args === false{
  491.             return false;
  492.         }
  493.         for ($i 0$i count($args)$i++{
  494.             if ($args[$i=== $this->_wildcard{
  495.                 $args[$inew AnythingExpectation();
  496.             }
  497.         }
  498.         return $args;
  499.     }
  500. }
  501.  
  502. /**
  503.  *    A type of SimpleMethodAction.
  504.  *    Stashes a reference for returning later.
  505.  *    @package SimpleTest
  506.  *    @subpackage MockObjects
  507.  */
  508.     var $_reference;
  509.     
  510.     /**
  511.      *    Stashes it for later.
  512.      *    @param mixed $reference     Actual PHP4 style reference.
  513.      *    @access public
  514.      */
  515.     function SimpleByReference(&$reference{
  516.         $this->_reference = &$reference;
  517.     }
  518.     
  519.     /**
  520.      *    Returns the reference stored earlier.
  521.      *    @return mixed    Whatever was stashed.
  522.      *    @access public
  523.      */
  524.     function &act({
  525.         return $this->_reference;
  526.     }
  527. }
  528.  
  529. /**
  530.  *    A type of SimpleMethodAction.
  531.  *    Stashes a value for returning later.
  532.  *    @package SimpleTest
  533.  *    @subpackage MockObjects
  534.  */
  535. class SimpleByValue {
  536.     var $_value;
  537.     
  538.     /**
  539.      *    Stashes it for later.
  540.      *    @param mixed $value     You need to clone objects
  541.      *                             if you want copy semantics
  542.      *                             for these.
  543.      *    @access public
  544.      */
  545.     function SimpleByValue($value{
  546.         $this->_value = $value;
  547.     }
  548.     
  549.     /**
  550.      *    Returns the value stored earlier.
  551.      *    @return mixed    Whatever was stashed.
  552.      *    @access public
  553.      */
  554.     function &act({
  555.         $dummy $this->_value;
  556.         return $dummy;
  557.     }
  558. }
  559.  
  560. /**
  561.  *    A type of SimpleMethodAction.
  562.  *    Stashes an exception for throwing later.
  563.  *    @package SimpleTest
  564.  *    @subpackage MockObjects
  565.  */
  566. class SimpleThrower {
  567.     var $_exception;
  568.     
  569.     /**
  570.      *    Stashes it for later.
  571.      *    @param Exception $exception    The exception object to throw.
  572.      *    @access public
  573.      */
  574.     function SimpleThrower($exception{
  575.         $this->_exception = $exception;
  576.     }
  577.     
  578.     /**
  579.      *    Throws the exceptins stashed earlier.
  580.      *    @access public
  581.      */
  582.     function act({
  583.         eval('throw $this->_exception;');
  584.     }
  585. }
  586.  
  587. /**
  588.  *    A type of SimpleMethodAction.
  589.  *    Stashes an error for emitting later.
  590.  *    @package SimpleTest
  591.  *    @subpackage MockObjects
  592.  */
  593.     var $_error;
  594.     var $_severity;
  595.     
  596.     /**
  597.      *    Stashes an error to throw later.
  598.      *    @param string $error      Error message.
  599.      *    @param integer $severity  PHP error constant, e.g E_USER_ERROR.
  600.      *    @access public
  601.      */
  602.     function SimpleErrorThrower($error$severity{
  603.         $this->_error = $error;
  604.         $this->_severity = $severity;
  605.     }
  606.     
  607.     /**
  608.      *    Triggers the stashed error.
  609.      *    @return null        The usual PHP4.4 shenanigans are needed here.
  610.      *    @access public
  611.      */
  612.     function &act({
  613.         trigger_error($this->_error$this->_severity);
  614.         $null null;
  615.         return $null;
  616.     }
  617. }
  618.  
  619. /**
  620.  *    A base class or delegate that extends an
  621.  *    empty collection of methods that can have their
  622.  *    return values set and expectations made of the
  623.  *    calls upon them. The mock will assert the
  624.  *    expectations against it's attached test case in
  625.  *    addition to the server stub behaviour or returning
  626.  *    preprogrammed responses.
  627.  *    @package SimpleTest
  628.  *    @subpackage MockObjects
  629.  */
  630. class SimpleMock {
  631.     var $_actions;
  632.     var $_wildcard = MOCK_ANYTHING;
  633.     var $_is_strict = true;
  634.     var $_call_counts;
  635.     var $_expected_counts;
  636.     var $_max_counts;
  637.     var $_expected_args;
  638.     var $_expected_args_at;
  639.  
  640.     /**
  641.      *    Creates an empty action list and expectation list.
  642.      *    All call counts are set to zero.
  643.      *    @access public
  644.      */
  645.     function SimpleMock({
  646.         $this->_actions = &new SimpleCallSchedule();
  647.         $this->_expectations &new SimpleCallSchedule();
  648.         $this->_call_counts = array();
  649.         $this->_expected_counts = array();
  650.         $this->_max_counts = array();
  651.         $this->_expected_args = array();
  652.         $this->_expected_args_at = array();
  653.         $test &$this->_getCurrentTestCase();
  654.         $test->tell($this);
  655.     }
  656.     
  657.     /**
  658.      *    Disables a name check when setting expectations.
  659.      *    This hack is needed for the partial mocks.
  660.      *    @access public
  661.      */
  662.     function disableExpectationNameChecks({
  663.         $this->_is_strict = false;
  664.     }
  665.  
  666.     /**
  667.      *    Finds currently running test.
  668.      *    @return SimpeTestCase    Current test case.
  669.      *    @access protected
  670.      */
  671.     function &_getCurrentTestCase({
  672.         $context &SimpleTest::getContext();
  673.         return $context->getTest();
  674.     }
  675.  
  676.     /**
  677.      *    Die if bad arguments array is passed.
  678.      *    @param mixed $args     The arguments value to be checked.
  679.      *    @param string $task    Description of task attempt.
  680.      *    @return boolean        Valid arguments
  681.      *    @access private
  682.      */
  683.     function _checkArgumentsIsArray($args$task{
  684.         if (is_array($args)) {
  685.             trigger_error(
  686.                 "Cannot $task as \$args parameter is not an array",
  687.                 E_USER_ERROR);
  688.         }
  689.     }
  690.  
  691.     /**
  692.      *    Triggers a PHP error if the method is not part
  693.      *    of this object.
  694.      *    @param string $method        Name of method.
  695.      *    @param string $task          Description of task attempt.
  696.      *    @access protected
  697.      */
  698.     function _dieOnNoMethod($method$task{
  699.         if ($this->_is_strict && method_exists($this$method)) {
  700.             trigger_error(
  701.                     "Cannot $task as no ${method}() in class get_class($this),
  702.                     E_USER_ERROR);
  703.         }
  704.     }
  705.  
  706.     /**
  707.      *    Replaces wildcard matches with wildcard
  708.      *    expectations in the argument list.
  709.      *    @param array $args      Raw argument list.
  710.      *    @return array           Argument list with
  711.      *                             expectations.
  712.      *    @access private
  713.      */
  714.     function _replaceWildcards($args{
  715.         if ($args === false{
  716.             return false;
  717.         }
  718.         for ($i 0$i count($args)$i++{
  719.             if ($args[$i=== $this->_wildcard{
  720.                 $args[$inew AnythingExpectation();
  721.             }
  722.         }
  723.         return $args;
  724.     }
  725.  
  726.     /**
  727.      *    Adds one to the call count of a method.
  728.      *    @param string $method        Method called.
  729.      *    @param array $args           Arguments as an array.
  730.      *    @access protected
  731.      */
  732.     function _addCall($method$args{
  733.         if (isset($this->_call_counts[$method])) {
  734.             $this->_call_counts[$method0;
  735.         }
  736.         $this->_call_counts[$method]++;
  737.     }
  738.  
  739.     /**
  740.      *    Fetches the call count of a method so far.
  741.      *    @param string $method        Method name called.
  742.      *    @return integer              Number of calls so far.
  743.      *    @access public
  744.      */
  745.     function getCallCount($method{
  746.         $this->_dieOnNoMethod($method"get call count");
  747.         $method strtolower($method);
  748.         if (isset($this->_call_counts[$method])) {
  749.             return 0;
  750.         }
  751.         return $this->_call_counts[$method];
  752.     }
  753.  
  754.     /**
  755.      *    Sets a return for a parameter list that will
  756.      *    be passed by value for all calls to this method.
  757.      *    @param string $method       Method name.
  758.      *    @param mixed $value         Result of call passed by value.
  759.      *    @param array $args          List of parameters to match
  760.      *                                 including wildcards.
  761.      *    @access public
  762.      */
  763.     function setReturnValue($method$value$args false{
  764.         $this->_dieOnNoMethod($method"set return value");
  765.         $this->_actions->register($method$argsnew SimpleByValue($value));
  766.     }
  767.  
  768.     /**
  769.      *    Sets a return for a parameter list that will
  770.      *    be passed by value only when the required call count
  771.      *    is reached.
  772.      *    @param integer $timing   Number of calls in the future
  773.      *                              to which the result applies. If
  774.      *                              not set then all calls will return
  775.      *                              the value.
  776.      *    @param string $method    Method name.
  777.      *    @param mixed $value      Result of call passed by value.
  778.      *    @param array $args       List of parameters to match
  779.      *                              including wildcards.
  780.      *    @access public
  781.      */
  782.     function setReturnValueAt($timing$method$value$args false{
  783.         $this->_dieOnNoMethod($method"set return value sequence");
  784.         $this->_actions->registerAt($timing$method$argsnew SimpleByValue($value));
  785.     }
  786.  
  787.     /**
  788.      *    Sets a return for a parameter list that will
  789.      *    be passed by reference for all calls.
  790.      *    @param string $method       Method name.
  791.      *    @param mixed $reference     Result of the call will be this object.
  792.      *    @param array $args          List of parameters to match
  793.      *                                 including wildcards.
  794.      *    @access public
  795.      */
  796.     function setReturnReference($method&$reference$args false{
  797.         $this->_dieOnNoMethod($method"set return reference");
  798.         $this->_actions->register($method$argsnew SimpleByReference($reference));
  799.     }
  800.  
  801.     /**
  802.      *    Sets a return for a parameter list that will
  803.      *    be passed by value only when the required call count
  804.      *    is reached.
  805.      *    @param integer $timing    Number of calls in the future
  806.      *                               to which the result applies. If
  807.      *                               not set then all calls will return
  808.      *                               the value.
  809.      *    @param string $method     Method name.
  810.      *    @param mixed $reference   Result of the call will be this object.
  811.      *    @param array $args        List of parameters to match
  812.      *                               including wildcards.
  813.      *    @access public
  814.      */
  815.     function setReturnReferenceAt($timing$method&$reference$args false{
  816.         $this->_dieOnNoMethod($method"set return reference sequence");
  817.         $this->_actions->registerAt($timing$method$argsnew SimpleByReference($reference));
  818.     }
  819.  
  820.     /**
  821.      *    Sets up an expected call with a set of
  822.      *    expected parameters in that call. All
  823.      *    calls will be compared to these expectations
  824.      *    regardless of when the call is made.
  825.      *    @param string $method        Method call to test.
  826.      *    @param array $args           Expected parameters for the call
  827.      *                                  including wildcards.
  828.      *    @param string $message       Overridden message.
  829.      *    @access public
  830.      */
  831.     function expect($method$args$message '%s'{
  832.         $this->_dieOnNoMethod($method'set expected arguments');
  833.         $this->_checkArgumentsIsArray($args'set expected arguments');
  834.         $this->_expectations->expectArguments($method$args$message);
  835.         $args $this->_replaceWildcards($args);
  836.         $message .= Mock::getExpectationLine();
  837.         $this->_expected_args[strtolower($method)=
  838.                 new ParametersExpectation($args$message);
  839.     }
  840.  
  841.     /**
  842.      *    @deprecated
  843.      */
  844.     function expectArguments($method$args$message '%s'{
  845.         return $this->expect($method$args$message);
  846.     }
  847.  
  848.     /**
  849.      *    Sets up an expected call with a set of
  850.      *    expected parameters in that call. The
  851.      *    expected call count will be adjusted if it
  852.      *    is set too low to reach this call.
  853.      *    @param integer $timing    Number of calls in the future at
  854.      *                               which to test. Next call is 0.
  855.      *    @param string $method     Method call to test.
  856.      *    @param array $args        Expected parameters for the call
  857.      *                               including wildcards.
  858.      *    @param string $message    Overridden message.
  859.      *    @access public
  860.      */
  861.     function expectAt($timing$method$args$message '%s'{
  862.         $this->_dieOnNoMethod($method'set expected arguments at time');
  863.         $this->_checkArgumentsIsArray($args'set expected arguments at time');
  864.         $args $this->_replaceWildcards($args);
  865.         if (isset($this->_expected_args_at[$timing])) {
  866.             $this->_expected_args_at[$timingarray();
  867.         }
  868.         $method strtolower($method);
  869.         $message .= Mock::getExpectationLine();
  870.         $this->_expected_args_at[$timing][$method=
  871.                 new ParametersExpectation($args$message);
  872.     }
  873.  
  874.     /**
  875.      *    @deprecated
  876.      */
  877.     function expectArgumentsAt($timing$method$args$message '%s'{
  878.         return $this->expectAt($timing$method$args$message);
  879.     }
  880.  
  881.     /**
  882.      *    Sets an expectation for the number of times
  883.      *    a method will be called. The tally method
  884.      *    is used to check this.
  885.      *    @param string $method        Method call to test.
  886.      *    @param integer $count        Number of times it should
  887.      *                                  have been called at tally.
  888.      *    @param string $message       Overridden message.
  889.      *    @access public
  890.      */
  891.     function expectCallCount($method$count$message '%s'{
  892.         $this->_dieOnNoMethod($method'set expected call count');
  893.         $message .= Mock::getExpectationLine();
  894.         $this->_expected_counts[strtolower($method)=
  895.                 new CallCountExpectation($method$count$message);
  896.     }
  897.  
  898.     /**
  899.      *    Sets the number of times a method may be called
  900.      *    before a test failure is triggered.
  901.      *    @param string $method        Method call to test.
  902.      *    @param integer $count        Most number of times it should
  903.      *                                  have been called.
  904.      *    @param string $message       Overridden message.
  905.      *    @access public
  906.      */
  907.     function expectMaximumCallCount($method$count$message '%s'{
  908.         $this->_dieOnNoMethod($method'set maximum call count');
  909.         $message .= Mock::getExpectationLine();
  910.         $this->_max_counts[strtolower($method)=
  911.                 new MaximumCallCountExpectation($method$count$message);
  912.     }
  913.  
  914.     /**
  915.      *    Sets the number of times to call a method to prevent
  916.      *    a failure on the tally.
  917.      *    @param string $method      Method call to test.
  918.      *    @param integer $count      Least number of times it should
  919.      *                                have been called.
  920.      *    @param string $message     Overridden message.
  921.      *    @access public
  922.      */
  923.     function expectMinimumCallCount($method$count$message '%s'{
  924.         $this->_dieOnNoMethod($method'set minimum call count');
  925.         $message .= Mock::getExpectationLine();
  926.         $this->_expected_counts[strtolower($method)=
  927.                 new MinimumCallCountExpectation($method$count$message);
  928.     }
  929.  
  930.     /**
  931.      *    Convenience method for barring a method
  932.      *    call.
  933.      *    @param string $method        Method call to ban.
  934.      *    @param string $message       Overridden message.
  935.      *    @access public
  936.      */
  937.     function expectNever($method$message '%s'{
  938.         $this->expectMaximumCallCount($method0$message);
  939.     }
  940.  
  941.     /**
  942.      *    Convenience method for a single method
  943.      *    call.
  944.      *    @param string $method     Method call to track.
  945.      *    @param array $args        Expected argument list or
  946.      *                               false for any arguments.
  947.      *    @param string $message    Overridden message.
  948.      *    @access public
  949.      */
  950.     function expectOnce($method$args false$message '%s'{
  951.         $this->expectCallCount($method1$message);
  952.         if ($args !== false{
  953.             $this->expect($method$args$message);
  954.         }
  955.     }
  956.  
  957.     /**
  958.      *    Convenience method for requiring a method
  959.      *    call.
  960.      *    @param string $method       Method call to track.
  961.      *    @param array $args          Expected argument list or
  962.      *                                 false for any arguments.
  963.      *    @param string $message      Overridden message.
  964.      *    @access public
  965.      */
  966.     function expectAtLeastOnce($method$args false$message '%s'{
  967.         $this->expectMinimumCallCount($method1$message);
  968.         if ($args !== false{
  969.             $this->expect($method$args$message);
  970.         }
  971.     }
  972.     
  973.     /**
  974.      *    Sets up a trigger to throw an exception upon the
  975.      *    method call.
  976.      *    @param string $method     Method name to throw on.
  977.      */
  978.     function throwOn($method$exception false$args false{
  979.         $this->_dieOnNoMethod($method"throw on");
  980.         $this->_actions->register($method$args,
  981.                 new SimpleThrower($exception $exception new Exception()));
  982.     }
  983.     
  984.     /**
  985.      *    Sets up a trigger to throw an exception upon the
  986.      *    method call.
  987.      */
  988.     function throwAt($timing$method$exception false$args false{
  989.         $this->_dieOnNoMethod($method"throw at");
  990.         $this->_actions->registerAt($timing$method$args,
  991.                 new SimpleThrower($exception $exception new Exception()));
  992.     }
  993.     
  994.     /**
  995.      *    Sets up a trigger to throw an error upon the
  996.      *    method call.
  997.      */
  998.     function errorOn($method$error 'A mock error'$args false$severity E_USER_ERROR{
  999.         $this->_dieOnNoMethod($method"error on");
  1000.         $this->_actions->register($method$argsnew SimpleErrorThrower($error$severity));
  1001.     }
  1002.     
  1003.     /**
  1004.      *    Sets up a trigger to throw an error upon the
  1005.      *    method call.
  1006.      */
  1007.     function errorAt($timing$method$error 'A mock error'$args false$severity E_USER_ERROR{
  1008.         $this->_dieOnNoMethod($method"error at");
  1009.         $this->_actions->registerAt($timing$method$argsnew SimpleErrorThrower($error$severity));
  1010.     }
  1011.  
  1012.     /**
  1013.      *    @deprecated
  1014.      */
  1015.     function tally({
  1016.     }
  1017.  
  1018.     /**
  1019.      *    Receives event from unit test that the current
  1020.      *    test method has finished. Totals up the call
  1021.      *    counts and triggers a test assertion if a test
  1022.      *    is present for expected call counts.
  1023.      *    @param string $test_method      Current method name.
  1024.      *    @param SimpleTestCase $test     Test to send message to.
  1025.      *    @access public
  1026.      */
  1027.     function atTestEnd($test_method&$test{
  1028.         foreach ($this->_expected_counts as $method => $expectation{
  1029.             $test->assert($expectation$this->getCallCount($method));
  1030.         }
  1031.         foreach ($this->_max_counts as $method => $expectation{
  1032.             if ($expectation->test($this->getCallCount($method))) {
  1033.                 $test->assert($expectation$this->getCallCount($method));
  1034.             }
  1035.         }
  1036.     }
  1037.  
  1038.     /**
  1039.      *    Returns the expected value for the method name
  1040.      *    and checks expectations. Will generate any
  1041.      *    test assertions as a result of expectations
  1042.      *    if there is a test present.
  1043.      *    @param string $method       Name of method to simulate.
  1044.      *    @param array $args          Arguments as an array.
  1045.      *    @return mixed               Stored return.
  1046.      *    @access private
  1047.      */
  1048.     function &_invoke($method$args{
  1049.         $method strtolower($method);
  1050.         $step $this->getCallCount($method);
  1051.         $this->_addCall($method$args);
  1052.         $this->_checkExpectations($method$args$step);
  1053.         $result &$this->_emulateCall($method$args$step);
  1054.         return $result;
  1055.     }
  1056.     
  1057.     /**
  1058.      *    Finds the return value matching the incoming
  1059.      *    arguments. If there is no matching value found
  1060.      *    then an error is triggered.
  1061.      *    @param string $method      Method name.
  1062.      *    @param array $args         Calling arguments.
  1063.      *    @param integer $step       Current position in the
  1064.      *                                call history.
  1065.      *    @return mixed              Stored return or other action.
  1066.      *    @access protected
  1067.      */
  1068.     function &_emulateCall($method$args$step{
  1069.         return $this->_actions->respond($step$method$args);
  1070.     }
  1071.  
  1072.     /**
  1073.      *    Tests the arguments against expectations.
  1074.      *    @param string $method        Method to check.
  1075.      *    @param array $args           Argument list to match.
  1076.      *    @param integer $timing       The position of this call
  1077.      *                                  in the call history.
  1078.      *    @access private
  1079.      */
  1080.     function _checkExpectations($method$args$timing{
  1081.         $test &$this->_getCurrentTestCase();
  1082.         if (isset($this->_max_counts[$method])) {
  1083.             if ($this->_max_counts[$method]->test($timing 1)) {
  1084.                 $test->assert($this->_max_counts[$method]$timing 1);
  1085.             }
  1086.         }
  1087.         if (isset($this->_expected_args_at[$timing][$method])) {
  1088.             $test->assert(
  1089.                     $this->_expected_args_at[$timing][$method],
  1090.                     $args,
  1091.                     "Mock method [$method] at [$timing] -> %s");
  1092.         elseif (isset($this->_expected_args[$method])) {
  1093.             $test->assert(
  1094.                     $this->_expected_args[$method],
  1095.                     $args,
  1096.                     "Mock method [$method] -> %s");
  1097.         }
  1098.     }
  1099. }
  1100.  
  1101. /**
  1102.  *    Static methods only service class for code generation of
  1103.  *    mock objects.
  1104.  *    @package SimpleTest
  1105.  *    @subpackage MockObjects
  1106.  */
  1107. class Mock {
  1108.  
  1109.     /**
  1110.      *    Factory for mock object classes.
  1111.      *    @access public
  1112.      */
  1113.     function Mock({
  1114.         trigger_error('Mock factory methods are static.');
  1115.     }
  1116.  
  1117.     /**
  1118.      *    Clones a class' interface and creates a mock version
  1119.      *    that can have return values and expectations set.
  1120.      *    @param string $class         Class to clone.
  1121.      *    @param string $mock_class    New class name. Default is
  1122.      *                                  the old name with "Mock"
  1123.      *                                  prepended.
  1124.      *    @param array $methods        Additional methods to add beyond
  1125.      *                                  those in the cloned class. Use this
  1126.      *                                  to emulate the dynamic addition of
  1127.      *                                  methods in the cloned class or when
  1128.      *                                  the class hasn't been written yet.
  1129.      *    @static
  1130.      *    @access public
  1131.      */
  1132.     function generate($class$mock_class false$methods false{
  1133.         $generator new MockGenerator($class$mock_class);
  1134.         return $generator->generateSubclass($methods);
  1135.     }
  1136.  
  1137.     /**
  1138.      *    Generates a version of a class with selected
  1139.      *    methods mocked only. Inherits the old class
  1140.      *    and chains the mock methods of an aggregated
  1141.      *    mock object.
  1142.      *    @param string $class            Class to clone.
  1143.      *    @param string $mock_class       New class name.
  1144.      *    @param array $methods           Methods to be overridden
  1145.      *                                     with mock versions.
  1146.      *    @static
  1147.      *    @access public
  1148.      */
  1149.     function generatePartial($class$mock_class$methods{
  1150.         $generator new MockGenerator($class$mock_class);
  1151.         return $generator->generatePartial($methods);
  1152.     }
  1153.  
  1154.     /**
  1155.      *    Uses a stack trace to find the line of an assertion.
  1156.      *    @access public
  1157.      *    @static
  1158.      */
  1159.     function getExpectationLine({
  1160.         $trace new SimpleStackTrace(array('expect'));
  1161.         return $trace->traceMethod();
  1162.     }
  1163. }
  1164.  
  1165. /**
  1166.  *    @package  SimpleTest
  1167.  *    @subpackage   MockObjects
  1168.  *    @deprecated
  1169.  */
  1170. class Stub extends Mock {
  1171. }
  1172.  
  1173. /**
  1174.  *    Service class for code generation of mock objects.
  1175.  *    @package SimpleTest
  1176.  *    @subpackage MockObjects
  1177.  */
  1178. class MockGenerator {
  1179.     var $_class;
  1180.     var $_mock_class;
  1181.     var $_mock_base;
  1182.     var $_reflection;
  1183.  
  1184.     /**
  1185.      *    Builds initial reflection object.
  1186.      *    @param string $class        Class to be mocked.
  1187.      *    @param string $mock_class   New class with identical interface,
  1188.      *                                 but no behaviour.
  1189.      */
  1190.     function MockGenerator($class$mock_class{
  1191.         $this->_class = $class;
  1192.         $this->_mock_class = $mock_class;
  1193.         if ($this->_mock_class{
  1194.             $this->_mock_class = 'Mock' $this->_class;
  1195.         }
  1196.         $this->_mock_base = SimpleTest::getMockBaseClass();
  1197.         $this->_reflection = new SimpleReflection($this->_class);
  1198.     }
  1199.  
  1200.     /**
  1201.      *    Clones a class' interface and creates a mock version
  1202.      *    that can have return values and expectations set.
  1203.      *    @param array $methods        Additional methods to add beyond
  1204.      *                                  those in th cloned class. Use this
  1205.      *                                  to emulate the dynamic addition of
  1206.      *                                  methods in the cloned class or when
  1207.      *                                  the class hasn't been written yet.
  1208.      *    @access public
  1209.      */
  1210.     function generate($methods{
  1211.         if ($this->_reflection->classOrInterfaceExists()) {
  1212.             return false;
  1213.         }
  1214.         $mock_reflection new SimpleReflection($this->_mock_class);
  1215.         if ($mock_reflection->classExistsSansAutoload()) {
  1216.             return false;
  1217.         }
  1218.         $code $this->_createClassCode($methods $methods array());
  1219.         return eval("$code return \$code;");
  1220.     }
  1221.     
  1222.     /**
  1223.      *    Subclasses a class and overrides every method with a mock one
  1224.      *    that can have return values and expectations set. Chains
  1225.      *    to an aggregated SimpleMock.
  1226.      *    @param array $methods        Additional methods to add beyond
  1227.      *                                  those in the cloned class. Use this
  1228.      *                                  to emulate the dynamic addition of
  1229.      *                                  methods in the cloned class or when
  1230.      *                                  the class hasn't been written yet.
  1231.      *    @access public
  1232.      */
  1233.     function generateSubclass($methods{
  1234.         if ($this->_reflection->classOrInterfaceExists()) {
  1235.             return false;
  1236.         }
  1237.         $mock_reflection new SimpleReflection($this->_mock_class);
  1238.         if ($mock_reflection->classExistsSansAutoload()) {
  1239.             return false;
  1240.         }
  1241.         if ($this->_reflection->isInterface(|| $this->_reflection->hasFinal()) {
  1242.             $code $this->_createClassCode($methods $methods array());
  1243.             return eval("$code return \$code;");
  1244.         else {
  1245.             $code $this->_createSubclassCode($methods $methods array());
  1246.             return eval("$code return \$code;");
  1247.         }
  1248.     }
  1249.  
  1250.     /**
  1251.      *    Generates a version of a class with selected
  1252.      *    methods mocked only. Inherits the old class
  1253.      *    and chains the mock methods of an aggregated
  1254.      *    mock object.
  1255.      *    @param array $methods           Methods to be overridden
  1256.      *                                     with mock versions.
  1257.      *    @access public
  1258.      */
  1259.     function generatePartial($methods{
  1260.         if ($this->_reflection->classExists($this->_class)) {
  1261.             return false;
  1262.         }
  1263.         $mock_reflection new SimpleReflection($this->_mock_class);
  1264.         if ($mock_reflection->classExistsSansAutoload()) {
  1265.             trigger_error('Partial mock class [' $this->_mock_class . '] already exists');
  1266.             return false;
  1267.         }
  1268.         $code $this->_extendClassCode($methods);
  1269.         return eval("$code return \$code;");
  1270.     }
  1271.  
  1272.     /**
  1273.      *    The new mock class code as a string.
  1274.      *    @param array $methods          Additional methods.
  1275.      *    @return string                 Code for new mock class.
  1276.      *    @access private
  1277.      */
  1278.     function _createClassCode($methods{
  1279.         $implements '';
  1280.         $interfaces $this->_reflection->getInterfaces();
  1281.         if (function_exists('spl_classes')) {
  1282.             $interfaces array_diff($interfacesarray('Traversable'));
  1283.         }
  1284.         if (count($interfaces0{
  1285.             $implements 'implements ' implode(', '$interfaces);
  1286.         }
  1287.         $code "class " $this->_mock_class . " extends " $this->_mock_base . " $implements {\n";
  1288.         $code .= "    function " $this->_mock_class . "() {\n";
  1289.         $code .= "        \$this->" $this->_mock_base . "();\n";
  1290.         $code .= "    }\n";
  1291.         if (in_array('__construct'$this->_reflection->getMethods())) {
  1292.             $code .= "    " $this->_reflection->getSignature('__construct'" {\n";
  1293.             $code .= "        \$this->" $this->_mock_base . "();\n";
  1294.             $code .= "    }\n";
  1295.         }
  1296.         $code .= $this->_createHandlerCode($methods);
  1297.         $code .= "}\n";
  1298.         return $code;
  1299.     }
  1300.  
  1301.     /**
  1302.      *    The new mock class code as a string. The mock will
  1303.      *    be a subclass of the original mocked class.
  1304.      *    @param array $methods          Additional methods.
  1305.      *    @return string                 Code for new mock class.
  1306.      *    @access private
  1307.      */
  1308.     function _createSubclassCode($methods{
  1309.         $code  "class " $this->_mock_class . " extends " $this->_class . " {\n";
  1310.         $code .= "    var \$_mock;\n";
  1311.         $code .= $this->_addMethodList(array_merge($methods$this->_reflection->getMethods()));
  1312.         $code .= "\n";
  1313.         $code .= "    function " $this->_mock_class . "() {\n";
  1314.         $code .= "        \$this->_mock = &new " $this->_mock_base . "();\n";
  1315.         $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
  1316.         $code .= "    }\n";
  1317.         $code .= $this->_chainMockReturns();
  1318.         $code .= $this->_chainMockExpectations();
  1319.         $code .= $this->_chainThrowMethods();
  1320.         $code .= $this->_overrideMethods($this->_reflection->getMethods());
  1321.         $code .= $this->_createNewMethodCode($methods);
  1322.         $code .= "}\n";
  1323.         return $code;
  1324.     }
  1325.  
  1326.     /**
  1327.      *    The extension class code as a string. The class
  1328.      *    composites a mock object and chains mocked methods
  1329.      *    to it.
  1330.      *    @param array  $methods       Mocked methods.
  1331.      *    @return string               Code for a new class.
  1332.      *    @access private
  1333.      */
  1334.     function _extendClassCode($methods{
  1335.         $code  "class " $this->_mock_class . " extends " $this->_class . " {\n";
  1336.         $code .= "    var \$_mock;\n";
  1337.         $code .= $this->_addMethodList($methods);
  1338.         $code .= "\n";
  1339.         $code .= "    function " $this->_mock_class . "() {\n";
  1340.         $code .= "        \$this->_mock = &new " $this->_mock_base . "();\n";
  1341.         $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
  1342.         $code .= "    }\n";
  1343.         $code .= $this->_chainMockReturns();
  1344.         $code .= $this->_chainMockExpectations();
  1345.         $code .= $this->_chainThrowMethods();
  1346.         $code .= $this->_overrideMethods($methods);
  1347.         $code .= "}\n";
  1348.         return $code;
  1349.     }
  1350.  
  1351.     /**
  1352.      *    Creates code within a class to generate replaced
  1353.      *    methods. All methods call the _invoke() handler
  1354.      *    with the method name and the arguments in an
  1355.      *    array.
  1356.      *    @param array $methods    Additional methods.
  1357.      *    @access private
  1358.      */
  1359.     function _createHandlerCode($methods{
  1360.         $code '';
  1361.         $methods array_merge($methods$this->_reflection->getMethods());
  1362.         foreach ($methods as $method{
  1363.             if ($this->_isConstructor($method)) {
  1364.                 continue;
  1365.             }
  1366.             $mock_reflection new SimpleReflection($this->_mock_base);
  1367.             if (in_array($method$mock_reflection->getMethods())) {
  1368.                 continue;
  1369.             }
  1370.             $code .= "    " $this->_reflection->getSignature($method" {\n";
  1371.             $code .= "        \$args = func_get_args();\n";
  1372.             $code .= "        \$result = &\$this->_invoke(\"$method\", \$args);\n";
  1373.             $code .= "        return \$result;\n";
  1374.             $code .= "    }\n";
  1375.         }
  1376.         return $code;
  1377.     }
  1378.  
  1379.     /**
  1380.      *    Creates code within a class to generate a new
  1381.      *    methods. All methods call the _invoke() handler
  1382.      *    on the internal mock with the method name and
  1383.      *    the arguments in an array.
  1384.      *    @param array $methods    Additional methods.
  1385.      *    @access private
  1386.      */
  1387.     function _createNewMethodCode($methods{
  1388.         $code '';
  1389.         foreach ($methods as $method{
  1390.             if ($this->_isConstructor($method)) {
  1391.                 continue;
  1392.             }
  1393.             $mock_reflection new SimpleReflection($this->_mock_base);
  1394.             if (in_array($method$mock_reflection->getMethods())) {
  1395.                 continue;
  1396.             }
  1397.             $code .= "    " $this->_reflection->getSignature($method" {\n";
  1398.             $code .= "        \$args = func_get_args();\n";
  1399.             $code .= "        \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
  1400.             $code .= "        return \$result;\n";
  1401.             $code .= "    }\n";
  1402.         }
  1403.         return $code;
  1404.     }
  1405.  
  1406.     /**
  1407.      *    Tests to see if a special PHP method is about to
  1408.      *    be stubbed by mistake.
  1409.      *    @param string $method    Method name.
  1410.      *    @return boolean          True if special.
  1411.      *    @access private
  1412.      */
  1413.     function _isConstructor($method{
  1414.         return in_array(
  1415.                 strtolower($method),
  1416.                 array('__construct''__destruct'));
  1417.     }
  1418.  
  1419.     /**
  1420.      *    Creates a list of mocked methods for error checking.
  1421.      *    @param array $methods       Mocked methods.
  1422.      *    @return string              Code for a method list.
  1423.      *    @access private
  1424.      */
  1425.     function _addMethodList($methods{
  1426.         return "    var \$_mocked_methods = array('" .
  1427.                 implode("', '"array_map('strtolower'$methods)) .
  1428.                 "');\n";
  1429.     }
  1430.  
  1431.     /**
  1432.      *    Creates code to abandon the expectation if not mocked.
  1433.      *    @param string $alias       Parameter name of method name.
  1434.      *    @return string             Code for bail out.
  1435.      *    @access private
  1436.      */
  1437.     function _bailOutIfNotMocked($alias{
  1438.         $code  "        if (! in_array(strtolower($alias), \$this->_mocked_methods)) {\n";
  1439.         $code .= "            trigger_error(\"Method [$alias] is not mocked\");\n";
  1440.         $code .= "            \$null = null;\n";
  1441.         $code .= "            return \$null;\n";
  1442.         $code .= "        }\n";
  1443.         return $code;
  1444.     }
  1445.  
  1446.     /**
  1447.      *    Creates source code for chaining to the composited
  1448.      *    mock object.
  1449.      *    @return string           Code for mock set up.
  1450.      *    @access private
  1451.      */
  1452.     function _chainMockReturns({
  1453.         $code  "    function setReturnValue(\$method, \$value, \$args = false) {\n";
  1454.         $code .= $this->_bailOutIfNotMocked("\$method");
  1455.         $code .= "        \$this->_mock->setReturnValue(\$method, \$value, \$args);\n";
  1456.         $code .= "    }\n";
  1457.         $code .= "    function setReturnValueAt(\$timing, \$method, \$value, \$args = false) {\n";
  1458.         $code .= $this->_bailOutIfNotMocked("\$method");
  1459.         $code .= "        \$this->_mock->setReturnValueAt(\$timing, \$method, \$value, \$args);\n";
  1460.         $code .= "    }\n";
  1461.         $code .= "    function setReturnReference(\$method, &\$ref, \$args = false) {\n";
  1462.         $code .= $this->_bailOutIfNotMocked("\$method");
  1463.         $code .= "        \$this->_mock->setReturnReference(\$method, \$ref, \$args);\n";
  1464.         $code .= "    }\n";
  1465.         $code .= "    function setReturnReferenceAt(\$timing, \$method, &\$ref, \$args = false) {\n";
  1466.         $code .= $this->_bailOutIfNotMocked("\$method");
  1467.         $code .= "        \$this->_mock->setReturnReferenceAt(\$timing, \$method, \$ref, \$args);\n";
  1468.         $code .= "    }\n";
  1469.         return $code;
  1470.     }
  1471.  
  1472.     /**
  1473.      *    Creates source code for chaining to an aggregated
  1474.      *    mock object.
  1475.      *    @return string                 Code for expectations.
  1476.      *    @access private
  1477.      */
  1478.     function _chainMockExpectations({
  1479.         $code  "    function expect(\$method, \$args = false, \$msg = '%s') {\n";
  1480.         $code .= $this->_bailOutIfNotMocked("\$method");
  1481.         $code .= "        \$this->_mock->expect(\$method, \$args, \$msg);\n";
  1482.         $code .= "    }\n";
  1483.         $code .= "    function expectArguments(\$method, \$args = false, \$msg = '%s') {\n";
  1484.         $code .= $this->_bailOutIfNotMocked("\$method");
  1485.         $code .= "        \$this->_mock->expectArguments(\$method, \$args, \$msg);\n";
  1486.         $code .= "    }\n";
  1487.         $code .= "    function expectAt(\$timing, \$method, \$args = false, \$msg = '%s') {\n";
  1488.         $code .= $this->_bailOutIfNotMocked("\$method");
  1489.         $code .= "        \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args, \$msg);\n";
  1490.         $code .= "    }\n";
  1491.         $code .= "    function expectArgumentsAt(\$timing, \$method, \$args = false, \$msg = '%s') {\n";
  1492.         $code .= $this->_bailOutIfNotMocked("\$method");
  1493.         $code .= "        \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args, \$msg);\n";
  1494.         $code .= "    }\n";
  1495.         $code .= "    function expectCallCount(\$method, \$count) {\n";
  1496.         $code .= $this->_bailOutIfNotMocked("\$method");
  1497.         $code .= "        \$this->_mock->expectCallCount(\$method, \$count, \$msg = '%s');\n";
  1498.         $code .= "    }\n";
  1499.         $code .= "    function expectMaximumCallCount(\$method, \$count, \$msg = '%s') {\n";
  1500.         $code .= $this->_bailOutIfNotMocked("\$method");
  1501.         $code .= "        \$this->_mock->expectMaximumCallCount(\$method, \$count, \$msg = '%s');\n";
  1502.         $code .= "    }\n";
  1503.         $code .= "    function expectMinimumCallCount(\$method, \$count, \$msg = '%s') {\n";
  1504.         $code .= $this->_bailOutIfNotMocked("\$method");
  1505.         $code .= "        \$this->_mock->expectMinimumCallCount(\$method, \$count, \$msg = '%s');\n";
  1506.         $code .= "    }\n";
  1507.         $code .= "    function expectNever(\$method) {\n";
  1508.         $code .= $this->_bailOutIfNotMocked("\$method");
  1509.         $code .= "        \$this->_mock->expectNever(\$method);\n";
  1510.         $code .= "    }\n";
  1511.         $code .= "    function expectOnce(\$method, \$args = false, \$msg = '%s') {\n";
  1512.         $code .= $this->_bailOutIfNotMocked("\$method");
  1513.         $code .= "        \$this->_mock->expectOnce(\$method, \$args, \$msg);\n";
  1514.         $code .= "    }\n";
  1515.         $code .= "    function expectAtLeastOnce(\$method, \$args = false, \$msg = '%s') {\n";
  1516.         $code .= $this->_bailOutIfNotMocked("\$method");
  1517.         $code .= "        \$this->_mock->expectAtLeastOnce(\$method, \$args, \$msg);\n";
  1518.         $code .= "    }\n";
  1519.         $code .= "    function tally() {\n";
  1520.         $code .= "    }\n";
  1521.         return $code;
  1522.     }
  1523.     
  1524.     /**
  1525.      *    Adds code for chaining the throw methods.
  1526.      *    @return string           Code for chains.
  1527.      *    @access private
  1528.      */
  1529.     function _chainThrowMethods({
  1530.         $code  "    function throwOn(\$method, \$exception = false, \$args = false) {\n";
  1531.         $code .= $this->_bailOutIfNotMocked("\$method");
  1532.         $code .= "        \$this->_mock->throwOn(\$method, \$exception, \$args);\n";
  1533.         $code .= "    }\n";
  1534.         $code .= "    function throwAt(\$timing, \$method, \$exception = false, \$args = false) {\n";
  1535.         $code .= $this->_bailOutIfNotMocked("\$method");
  1536.         $code .= "        \$this->_mock->throwAt(\$timing, \$method, \$exception, \$args);\n";
  1537.         $code .= "    }\n";
  1538.         $code .= "    function errorOn(\$method, \$error = 'A mock error', \$args = false, \$severity = E_USER_ERROR) {\n";
  1539.         $code .= $this->_bailOutIfNotMocked("\$method");
  1540.         $code .= "        \$this->_mock->errorOn(\$method, \$error, \$args, \$severity);\n";
  1541.         $code .= "    }\n";
  1542.         $code .= "    function errorAt(\$timing, \$method, \$error = 'A mock error', \$args = false, \$severity = E_USER_ERROR) {\n";
  1543.         $code .= $this->_bailOutIfNotMocked("\$method");
  1544.         $code .= "        \$this->_mock->errorAt(\$timing, \$method, \$error, \$args, \$severity);\n";
  1545.         $code .= "    }\n";
  1546.         return $code;
  1547.     }
  1548.  
  1549.     /**
  1550.      *    Creates source code to override a list of methods
  1551.      *    with mock versions.
  1552.      *    @param array $methods    Methods to be overridden
  1553.      *                              with mock versions.
  1554.      *    @return string           Code for overridden chains.
  1555.      *    @access private
  1556.      */
  1557.     function _overrideMethods($methods{
  1558.         $code "";
  1559.         foreach ($methods as $method{
  1560.             if ($this->_isConstructor($method)) {
  1561.                 continue;
  1562.             }
  1563.             $code .= "    " $this->_reflection->getSignature($method" {\n";
  1564.             $code .= "        \$args = func_get_args();\n";
  1565.             $code .= "        \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
  1566.             $code .= "        return \$result;\n";
  1567.             $code .= "    }\n";
  1568.         }
  1569.         return $code;
  1570.     }
  1571. }
  1572. ?>

Documentation generated on Sun, 04 May 2008 09:21:47 -0500 by phpDocumentor 1.3.0