[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/tests_runner/lib/simpletest/ -> mock_objects.php (source)

   1  <?php
   2      /**

   3       *    base include file for SimpleTest

   4       *    @package    SimpleTest

   5       *    @subpackage    MockObjects

   6       *    @version    $Id: mock_objects.php 5999 2007-06-18 13:13:08Z pachanga $

   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      /**

  23       * Default character simpletest will substitute for any value

  24       */
  25      if (! defined('MOCK_ANYTHING')) {
  26          define('MOCK_ANYTHING', '*');
  27      }
  28  
  29      /**

  30       *    Parameter comparison assertion.

  31       *    @package SimpleTest

  32       *    @subpackage MockObjects

  33       */
  34      class ParametersExpectation extends SimpleExpectation {
  35          var $_expected;
  36  
  37          /**

  38           *    Sets the expected parameter list.

  39           *    @param array $parameters  Array of parameters including

  40           *                              those that are wildcarded.

  41           *                              If the value is not an array

  42           *                              then it is considered to match any.

  43           *    @param string $message    Customised message on failure.

  44           *    @access public

  45           */
  46          function ParametersExpectation($expected = false, $message = '%s') {
  47              $this->SimpleExpectation($message);
  48              $this->_expected = $expected;
  49          }
  50  
  51          /**

  52           *    Tests the assertion. True if correct.

  53           *    @param array $parameters     Comparison values.

  54           *    @return boolean              True if correct.

  55           *    @access public

  56           */
  57          function test($parameters) {
  58              if (! is_array($this->_expected)) {
  59                  return true;
  60              }
  61              if (count($this->_expected) != count($parameters)) {
  62                  return false;
  63              }
  64              for ($i = 0; $i < count($this->_expected); $i++) {
  65                  if (! $this->_testParameter($parameters[$i], $this->_expected[$i])) {
  66                      return false;
  67                  }
  68              }
  69              return true;
  70          }
  71  
  72          /**

  73           *    Tests an individual parameter.

  74           *    @param mixed $parameter    Value to test.

  75           *    @param mixed $expected     Comparison value.

  76           *    @return boolean            True if expectation

  77           *                               fulfilled.

  78           *    @access private

  79           */
  80          function _testParameter($parameter, $expected) {
  81              $comparison = $this->_coerceToExpectation($expected);
  82              return $comparison->test($parameter);
  83          }
  84  
  85          /**

  86           *    Returns a human readable test message.

  87           *    @param array $comparison   Incoming parameter list.

  88           *    @return string             Description of success

  89           *                               or failure.

  90           *    @access public

  91           */
  92          function testMessage($parameters) {
  93              if ($this->test($parameters)) {
  94                  return "Expectation of " . count($this->_expected) .
  95                          " arguments of [" . $this->_renderArguments($this->_expected) .
  96                          "] is correct";
  97              } else {
  98                  return $this->_describeDifference($this->_expected, $parameters);
  99              }
 100          }
 101  
 102          /**

 103           *    Message to display if expectation differs from

 104           *    the parameters actually received.

 105           *    @param array $expected      Expected parameters as list.

 106           *    @param array $parameters    Actual parameters received.

 107           *    @return string              Description of difference.

 108           *    @access private

 109           */
 110          function _describeDifference($expected, $parameters) {
 111              if (count($expected) != count($parameters)) {
 112                  return "Expected " . count($expected) .
 113                          " arguments of [" . $this->_renderArguments($expected) .
 114                          "] but got " . count($parameters) .
 115                          " arguments of [" . $this->_renderArguments($parameters) . "]";
 116              }
 117              $messages = array();
 118              for ($i = 0; $i < count($expected); $i++) {
 119                  $comparison = $this->_coerceToExpectation($expected[$i]);
 120                  if (! $comparison->test($parameters[$i])) {
 121                      $messages[] = "parameter " . ($i + 1) . " with [" .
 122                              $comparison->overlayMessage($parameters[$i], $this->_getDumper()) . "]";
 123                  }
 124              }
 125              return "Parameter expectation differs at " . implode(" and ", $messages);
 126          }
 127  
 128          /**

 129           *    Creates an identical expectation if the

 130           *    object/value is not already some type

 131           *    of expectation.

 132           *    @param mixed $expected      Expected value.

 133           *    @return SimpleExpectation   Expectation object.

 134           *    @access private

 135           */
 136          function _coerceToExpectation($expected) {
 137              if (SimpleExpectation::isExpectation($expected)) {
 138                  return $expected;
 139              }
 140              return new IdenticalExpectation($expected);
 141          }
 142  
 143          /**

 144           *    Renders the argument list as a string for

 145           *    messages.

 146           *    @param array $args    Incoming arguments.

 147           *    @return string        Simple description of type and value.

 148           *    @access private

 149           */
 150          function _renderArguments($args) {
 151              $descriptions = array();
 152              if (is_array($args)) {
 153                  foreach ($args as $arg) {
 154                      $dumper = &new SimpleDumper();
 155                      $descriptions[] = $dumper->describeValue($arg);
 156                  }
 157              }
 158              return implode(', ', $descriptions);
 159          }
 160      }
 161  
 162      /**

 163       *    Confirms that the number of calls on a method is as expected.

 164       *    @package    SimpleTest

 165       *    @subpackage    MockObjects

 166       */
 167      class CallCountExpectation extends SimpleExpectation {
 168          var $_method;
 169          var $_count;
 170  
 171          /**

 172           *    Stashes the method and expected count for later

 173           *    reporting.

 174           *    @param string $method    Name of method to confirm against.

 175           *    @param integer $count    Expected number of calls.

 176           *    @param string $message   Custom error message.

 177           */
 178          function CallCountExpectation($method, $count, $message = '%s') {
 179              $this->_method = $method;
 180              $this->_count = $count;
 181              $this->SimpleExpectation($message);
 182          }
 183  
 184          /**

 185           *    Tests the assertion. True if correct.

 186           *    @param integer $compare     Measured call count.

 187           *    @return boolean             True if expected.

 188           *    @access public

 189           */
 190          function test($compare) {
 191              return ($this->_count == $compare);
 192          }
 193  
 194          /**

 195           *    Reports the comparison.

 196           *    @param integer $compare     Measured call count.

 197           *    @return string              Message to show.

 198           *    @access public

 199           */
 200          function testMessage($compare) {
 201              return 'Expected call count for [' . $this->_method .
 202                      '] was [' . $this->_count .
 203                      '] got [' . $compare . ']';
 204          }
 205      }
 206  
 207      /**

 208       *    Confirms that the number of calls on a method is as expected.

 209       *    @package    SimpleTest

 210       *    @subpackage    MockObjects

 211       */
 212      class MinimumCallCountExpectation extends SimpleExpectation {
 213          var $_method;
 214          var $_count;
 215  
 216          /**

 217           *    Stashes the method and expected count for later

 218           *    reporting.

 219           *    @param string $method    Name of method to confirm against.

 220           *    @param integer $count    Minimum number of calls.

 221           *    @param string $message   Custom error message.

 222           */
 223          function MinimumCallCountExpectation($method, $count, $message = '%s') {
 224              $this->_method = $method;
 225              $this->_count = $count;
 226              $this->SimpleExpectation($message);
 227          }
 228  
 229          /**

 230           *    Tests the assertion. True if correct.

 231           *    @param integer $compare     Measured call count.

 232           *    @return boolean             True if enough.

 233           *    @access public

 234           */
 235          function test($compare) {
 236              return ($this->_count <= $compare);
 237          }
 238  
 239          /**

 240           *    Reports the comparison.

 241           *    @param integer $compare     Measured call count.

 242           *    @return string              Message to show.

 243           *    @access public

 244           */
 245          function testMessage($compare) {
 246              return 'Minimum call count for [' . $this->_method .
 247                      '] was [' . $this->_count .
 248                      '] got [' . $compare . ']';
 249          }
 250      }
 251  
 252      /**

 253       *    Confirms that the number of calls on a method is as expected.

 254       *    @package    SimpleTest

 255       *    @subpackage    MockObjects

 256       */
 257      class MaximumCallCountExpectation extends SimpleExpectation {
 258          var $_method;
 259          var $_count;
 260  
 261          /**

 262           *    Stashes the method and expected count for later

 263           *    reporting.

 264           *    @param string $method    Name of method to confirm against.

 265           *    @param integer $count    Minimum number of calls.

 266           *    @param string $message   Custom error message.

 267           */
 268          function MaximumCallCountExpectation($method, $count, $message = '%s') {
 269              $this->_method = $method;
 270              $this->_count = $count;
 271              $this->SimpleExpectation($message);
 272          }
 273  
 274          /**

 275           *    Tests the assertion. True if correct.

 276           *    @param integer $compare     Measured call count.

 277           *    @return boolean             True if not over.

 278           *    @access public

 279           */
 280          function test($compare) {
 281              return ($this->_count >= $compare);
 282          }
 283  
 284          /**

 285           *    Reports the comparison.

 286           *    @param integer $compare     Measured call count.

 287           *    @return string              Message to show.

 288           *    @access public

 289           */
 290          function testMessage($compare) {
 291              return 'Maximum call count for [' . $this->_method .
 292                      '] was [' . $this->_count .
 293                      '] got [' . $compare . ']';
 294          }
 295      }
 296  
 297      /**

 298       *    Retrieves values and references by searching the

 299       *    parameter lists until a match is found.

 300       *    @package SimpleTest

 301       *    @subpackage MockObjects

 302       */
 303      class CallMap {
 304          var $_map;
 305  
 306          /**

 307           *    Creates an empty call map.

 308           *    @access public

 309           */
 310          function CallMap() {
 311              $this->_map = array();
 312          }
 313  
 314          /**

 315           *    Stashes a value against a method call.

 316           *    @param array $parameters    Arguments including wildcards.

 317           *    @param mixed $value         Value copied into the map.

 318           *    @access public

 319           */
 320          function addValue($parameters, $value) {
 321              $this->addReference($parameters, $value);
 322          }
 323  
 324          /**

 325           *    Stashes a reference against a method call.

 326           *    @param array $parameters    Array of arguments (including wildcards).

 327           *    @param mixed $reference     Array reference placed in the map.

 328           *    @access public

 329           */
 330          function addReference($parameters, &$reference) {
 331              $place = count($this->_map);
 332              $this->_map[$place] = array();
 333              $this->_map[$place]["params"] = new ParametersExpectation($parameters);
 334              $this->_map[$place]["content"] = &$reference;
 335          }
 336  
 337          /**

 338           *    Searches the call list for a matching parameter

 339           *    set. Returned by reference.

 340           *    @param array $parameters    Parameters to search by

 341           *                                without wildcards.

 342           *    @return object              Object held in the first matching

 343           *                                slot, otherwise null.

 344           *    @access public

 345           */
 346          function &findFirstMatch($parameters) {
 347              $slot = $this->_findFirstSlot($parameters);
 348              if (!isset($slot)) {
 349                  $null = null;
 350                  return $null;
 351              }
 352              return $slot["content"];
 353          }
 354  
 355          /**

 356           *    Searches the call list for a matching parameter

 357           *    set. True if successful.

 358           *    @param array $parameters    Parameters to search by

 359           *                                without wildcards.

 360           *    @return boolean             True if a match is present.

 361           *    @access public

 362           */
 363          function isMatch($parameters) {
 364              return ($this->_findFirstSlot($parameters) != null);
 365          }
 366  
 367          /**

 368           *    Searches the map for a matching item.

 369           *    @param array $parameters    Parameters to search by

 370           *                                without wildcards.

 371           *    @return array               Reference to slot or null.

 372           *    @access private

 373           */
 374          function &_findFirstSlot($parameters) {
 375              $count = count($this->_map);
 376              for ($i = 0; $i < $count; $i++) {
 377                  if ($this->_map[$i]["params"]->test($parameters)) {
 378                      return $this->_map[$i];
 379                  }
 380              }
 381              $null = null;
 382              return $null;
 383          }
 384      }
 385  
 386      /**

 387       *    An empty collection of methods that can have their

 388       *    return values set and expectations made of the

 389       *    calls upon them. The mock will assert the

 390       *    expectations against it's attached test case in

 391       *    addition to the server stub behaviour.

 392       *    @package SimpleTest

 393       *    @subpackage MockObjects

 394       */
 395      class SimpleMock {
 396          var $_wildcard = MOCK_ANYTHING;
 397          var $_is_strict = true;
 398          var $_returns;
 399          var $_return_sequence;
 400          var $_call_counts;
 401          var $_expected_counts;
 402          var $_max_counts;
 403          var $_expected_args;
 404          var $_expected_args_at;
 405  
 406          /**

 407           *    Creates an empty return list and expectation list.

 408           *    All call counts are set to zero.

 409           */
 410          function SimpleMock() {
 411              $this->_returns = array();
 412              $this->_return_sequence = array();
 413              $this->_call_counts = array();
 414              $this->_expected_counts = array();
 415              $this->_max_counts = array();
 416              $this->_expected_args = array();
 417              $this->_expected_args_at = array();
 418              $test = &$this->_getCurrentTestCase();
 419              $test->tell($this);
 420          }
 421          
 422          /**

 423           *    Disables a name check when setting expectations.

 424           *    This hack is needed for the partial mocks.

 425           *    @access public

 426           */
 427          function disableExpectationNameChecks() {
 428              $this->_is_strict = false;
 429          }
 430  
 431          /**

 432           *    Finds currently running test.

 433           *    @return SimpeTestCase    Current test case.

 434           *    @access protected

 435           */
 436          function &_getCurrentTestCase() {
 437              $context = &SimpleTest::getContext();
 438              return $context->getTest();
 439          }
 440  
 441          /**

 442           *    Die if bad arguments array is passed

 443           *    @param mixed $args     The arguments value to be checked.

 444           *    @param string $task    Description of task attempt.

 445           *    @return boolean        Valid arguments

 446           *    @access private

 447           */
 448          function _checkArgumentsIsArray($args, $task) {
 449              if (! is_array($args)) {
 450                  trigger_error(
 451                      "Cannot $task as \$args parameter is not an array",
 452                      E_USER_ERROR);
 453              }
 454          }
 455  
 456          /**

 457           *    Triggers a PHP error if the method is not part

 458           *    of this object.

 459           *    @param string $method        Name of method.

 460           *    @param string $task          Description of task attempt.

 461           *    @access protected

 462           */
 463          function _dieOnNoMethod($method, $task) {
 464              if ($this->_is_strict && ! method_exists($this, $method)) {
 465                  trigger_error(
 466                          "Cannot $task as no $method}() in class " . get_class($this),
 467                          E_USER_ERROR);
 468              }
 469          }
 470  
 471          /**

 472           *    Replaces wildcard matches with wildcard

 473           *    expectations in the argument list.

 474           *    @param array $args      Raw argument list.

 475           *    @return array           Argument list with

 476           *                            expectations.

 477           *    @access private

 478           */
 479          function _replaceWildcards($args) {
 480              if ($args === false) {
 481                  return false;
 482              }
 483              for ($i = 0; $i < count($args); $i++) {
 484                  if ($args[$i] === $this->_wildcard) {
 485                      $args[$i] = new AnythingExpectation();
 486                  }
 487              }
 488              return $args;
 489          }
 490  
 491          /**

 492           *    Adds one to the call count of a method.

 493           *    @param string $method        Method called.

 494           *    @param array $args           Arguments as an array.

 495           *    @access protected

 496           */
 497          function _addCall($method, $args) {
 498              if (!isset($this->_call_counts[$method])) {
 499                  $this->_call_counts[$method] = 0;
 500              }
 501              $this->_call_counts[$method]++;
 502          }
 503  
 504          /**

 505           *    Fetches the call count of a method so far.

 506           *    @param string $method        Method name called.

 507           *    @return                      Number of calls so far.

 508           *    @access public

 509           */
 510          function getCallCount($method) {
 511              $this->_dieOnNoMethod($method, "get call count");
 512              $method = strtolower($method);
 513              if (! isset($this->_call_counts[$method])) {
 514                  return 0;
 515              }
 516              return $this->_call_counts[$method];
 517          }
 518  
 519          /**

 520           *    Sets a return for a parameter list that will

 521           *    be passed by value for all calls to this method.

 522           *    @param string $method       Method name.

 523           *    @param mixed $value         Result of call passed by value.

 524           *    @param array $args          List of parameters to match

 525           *                                including wildcards.

 526           *    @access public

 527           */
 528          function setReturnValue($method, $value, $args = false) {
 529              $this->_dieOnNoMethod($method, "set return value");
 530              $args = $this->_replaceWildcards($args);
 531              $method = strtolower($method);
 532              if (! isset($this->_returns[$method])) {
 533                  $this->_returns[$method] = new CallMap();
 534              }
 535              $this->_returns[$method]->addValue($args, $value);
 536          }
 537  
 538          /**

 539           *    Sets a return for a parameter list that will

 540           *    be passed by value only when the required call count

 541           *    is reached.

 542           *    @param integer $timing   Number of calls in the future

 543           *                             to which the result applies. If

 544           *                             not set then all calls will return

 545           *                             the value.

 546           *    @param string $method    Method name.

 547           *    @param mixed $value      Result of call passed by value.

 548           *    @param array $args       List of parameters to match

 549           *                             including wildcards.

 550           *    @access public

 551           */
 552          function setReturnValueAt($timing, $method, $value, $args = false) {
 553              $this->_dieOnNoMethod($method, "set return value sequence");
 554              $args = $this->_replaceWildcards($args);
 555              $method = strtolower($method);
 556              if (! isset($this->_return_sequence[$method])) {
 557                  $this->