[ Index ]
 

Code source de PRADO 3.0.6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/tests/test_tools/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 1526 2006-11-28 23:34:00Z wei $
   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       *    A wildcard expectation always matches.
  31       *    @package SimpleTest
  32       *    @subpackage MockObjects
  33       */
  34      class AnythingExpectation extends SimpleExpectation {
  35  
  36          /**
  37           *    Tests the expectation. Always true.
  38           *    @param mixed $compare  Ignored.
  39           *    @return boolean        True.
  40           *    @access public
  41           */
  42          function test($compare) {
  43              return true;
  44          }
  45  
  46          /**
  47           *    Returns a human readable test message.
  48           *    @param mixed $compare      Comparison value.
  49           *    @return string             Description of success
  50           *                               or failure.
  51           *    @access public
  52           */
  53          function testMessage($compare) {
  54              $dumper = $this->_getDumper();
  55              return 'Anything always matches [' . $dumper->describeValue($compare) . ']';
  56          }
  57      }
  58  
  59      /**
  60       *    Parameter comparison assertion.
  61       *    @package SimpleTest
  62       *    @subpackage MockObjects
  63       */
  64      class ParametersExpectation extends SimpleExpectation {
  65          protected $_expected;
  66  
  67          /**
  68           *    Sets the expected parameter list.
  69           *    @param array $parameters  Array of parameters including
  70           *                              those that are wildcarded.
  71           *                              If the value is not an array
  72           *                              then it is considered to match any.
  73           *    @param mixed $wildcard    Any parameter matching this
  74           *                              will always match.
  75           *    @param string $message    Customised message on failure.
  76           *    @access public
  77           */
  78          function ParametersExpectation($expected = false, $message = '%s') {
  79              $this->SimpleExpectation($message);
  80              $this->_expected = $expected;
  81          }
  82  
  83          /**
  84           *    Tests the assertion. True if correct.
  85           *    @param array $parameters     Comparison values.
  86           *    @return boolean              True if correct.
  87           *    @access public
  88           */
  89          function test($parameters) {
  90              if (! is_array($this->_expected)) {
  91                  return true;
  92              }
  93              if (count($this->_expected) != count($parameters)) {
  94                  return false;
  95              }
  96              for ($i = 0; $i < count($this->_expected); $i++) {
  97                  if (! $this->_testParameter($parameters[$i], $this->_expected[$i])) {
  98                      return false;
  99                  }
 100              }
 101              return true;
 102          }
 103  
 104          /**
 105           *    Tests an individual parameter.
 106           *    @param mixed $parameter    Value to test.
 107           *    @param mixed $expected     Comparison value.
 108           *    @return boolean            True if expectation
 109           *                               fulfilled.
 110           *    @access private
 111           */
 112          function _testParameter($parameter, $expected) {
 113              $comparison = $this->_coerceToExpectation($expected);
 114              return $comparison->test($parameter);
 115          }
 116  
 117          /**
 118           *    Returns a human readable test message.
 119           *    @param array $comparison   Incoming parameter list.
 120           *    @return string             Description of success
 121           *                               or failure.
 122           *    @access public
 123           */
 124          function testMessage($parameters) {
 125              if ($this->test($parameters)) {
 126                  return "Expectation of " . count($this->_expected) .
 127                          " arguments of [" . $this->_renderArguments($this->_expected) .
 128                          "] is correct";
 129              } else {
 130                  return $this->_describeDifference($this->_expected, $parameters);
 131              }
 132          }
 133  
 134          /**
 135           *    Message to display if expectation differs from
 136           *    the parameters actually received.
 137           *    @param array $expected      Expected parameters as list.
 138           *    @param array $parameters    Actual parameters received.
 139           *    @return string              Description of difference.
 140           *    @access private
 141           */
 142          function _describeDifference($expected, $parameters) {
 143              if (count($expected) != count($parameters)) {
 144                  return "Expected " . count($expected) .
 145                          " arguments of [" . $this->_renderArguments($expected) .
 146                          "] but got " . count($parameters) .
 147                          " arguments of [" . $this->_renderArguments($parameters) . "]";
 148              }
 149              $messages = array();
 150              for ($i = 0; $i < count($expected); $i++) {
 151                  $comparison = $this->_coerceToExpectation($expected[$i]);
 152                  if (! $comparison->test($parameters[$i])) {
 153                      $messages[] = "parameter " . ($i + 1) . " with [" .
 154                              $comparison->overlayMessage($parameters[$i]) . "]";
 155                  }
 156              }
 157              return "Parameter expectation differs at " . implode(" and ", $messages);
 158          }
 159  
 160          /**
 161           *    Creates an identical expectation if the
 162           *    object/value is not already some type
 163           *    of expectation.
 164           *    @param mixed $expected      Expected value.
 165           *    @return SimpleExpectation   Expectation object.
 166           *    @access private
 167           */
 168          function _coerceToExpectation($expected) {
 169              if (SimpleExpectation::isExpectation($expected)) {
 170                  return $expected;
 171              }
 172              return new IdenticalExpectation($expected);
 173          }
 174  
 175          /**
 176           *    Renders the argument list as a string for
 177           *    messages.
 178           *    @param array $args    Incoming arguments.
 179           *    @return string        Simple description of type and value.
 180           *    @access private
 181           */
 182          function _renderArguments($args) {
 183              $descriptions = array();
 184              if (is_array($args)) {
 185                  foreach ($args as $arg) {
 186                      $dumper = new SimpleDumper();
 187                      $descriptions[] = $dumper->describeValue($arg);
 188                  }
 189              }
 190              return implode(', ', $descriptions);
 191          }
 192      }
 193  
 194      /**
 195       *    Confirms that the number of calls on a method is as expected.
 196       */
 197      class CallCountExpectation extends SimpleExpectation {
 198          protected $_method;
 199          protected $_count;
 200  
 201          /**
 202           *    Stashes the method and expected count for later
 203           *    reporting.
 204           *    @param string $method    Name of method to confirm against.
 205           *    @param integer $count    Expected number of calls.
 206           *    @param string $message   Custom error message.
 207           */
 208          function CallCountExpectation($method, $count, $message = '%s') {
 209              $this->_method = $method;
 210              $this->_count = $count;
 211              $this->SimpleExpectation($message);
 212          }
 213  
 214          /**
 215           *    Tests the assertion. True if correct.
 216           *    @param integer $compare     Measured call count.
 217           *    @return boolean             True if expected.
 218           *    @access public
 219           */
 220          function test($compare) {
 221              return ($this->_count == $compare);
 222          }
 223  
 224          /**
 225           *    Reports the comparison.
 226           *    @param integer $compare     Measured call count.
 227           *    @return string              Message to show.
 228           *    @access public
 229           */
 230          function testMessage($compare) {
 231              return 'Expected call count for [' . $this->_method .
 232                      '] was [' . $this->_count .
 233                      '] got [' . $compare . ']';
 234          }
 235      }
 236  
 237      /**
 238       *    Confirms that the number of calls on a method is as expected.
 239       */
 240      class MinimumCallCountExpectation extends SimpleExpectation {
 241          protected $_method;
 242          protected $_count;
 243  
 244          /**
 245           *    Stashes the method and expected count for later
 246           *    reporting.
 247           *    @param string $method    Name of method to confirm against.
 248           *    @param integer $count    Minimum number of calls.
 249           *    @param string $message   Custom error message.
 250           */
 251          function MinimumCallCountExpectation($method, $count, $message = '%s') {
 252              $this->_method = $method;
 253              $this->_count = $count;
 254              $this->SimpleExpectation($message);
 255          }
 256  
 257          /**
 258           *    Tests the assertion. True if correct.
 259           *    @param integer $compare     Measured call count.
 260           *    @return boolean             True if enough.
 261           *    @access public
 262           */
 263          function test($compare) {
 264              return ($this->_count <= $compare);
 265          }
 266  
 267          /**
 268           *    Reports the comparison.
 269           *    @param integer $compare     Measured call count.
 270           *    @return string              Message to show.
 271           *    @access public
 272           */
 273          function testMessage($compare) {
 274              return 'Minimum call count for [' . $this->_method .
 275                      '] was [' . $this->_count .
 276                      '] got [' . $compare . ']';
 277          }
 278      }
 279  
 280      /**
 281       *    Confirms that the number of calls on a method is as expected.
 282       */
 283      class MaximumCallCountExpectation extends SimpleExpectation {
 284          protected $_method;
 285          protected $_count;
 286  
 287          /**
 288           *    Stashes the method and expected count for later
 289           *    reporting.
 290           *    @param string $method    Name of method to confirm against.
 291           *    @param integer $count    Minimum number of calls.
 292           *    @param string $message   Custom error message.
 293           */
 294          function MaximumCallCountExpectation($method, $count, $message = '%s') {
 295              $this->_method = $method;
 296              $this->_count = $count;
 297              $this->SimpleExpectation($message);
 298          }
 299  
 300          /**
 301           *    Tests the assertion. True if correct.
 302           *    @param integer $compare     Measured call count.
 303           *    @return boolean             True if not over.
 304           *    @access public
 305           */
 306          function test($compare) {
 307              return ($this->_count >= $compare);
 308          }
 309  
 310          /**
 311           *    Reports the comparison.
 312           *    @param integer $compare     Measured call count.
 313           *    @return string              Message to show.
 314           *    @access public
 315           */
 316          function testMessage($compare) {
 317              return 'Maximum call count for [' . $this->_method .
 318                      '] was [' . $this->_count .
 319                      '] got [' . $compare . ']';
 320          }
 321      }
 322  
 323      /**
 324       *    Retrieves values and references by searching the
 325       *    parameter lists until a match is found.
 326       *    @package SimpleTest
 327       *    @subpackage MockObjects
 328       */
 329      class CallMap {
 330          protected $_map;
 331  
 332          /**
 333           *    Creates an empty call map.
 334           *    @access public
 335           */
 336          function CallMap() {
 337              $this->_map = array();
 338          }
 339  
 340          /**
 341           *    Stashes a value against a method call.
 342           *    @param array $parameters    Arguments including wildcards.
 343           *    @param mixed $value         Value copied into the map.
 344           *    @access public
 345           */
 346          function addValue($parameters, $value) {
 347              $this->addReference($parameters, $value);
 348          }
 349  
 350          /**
 351           *    Stashes a reference against a method call.
 352           *    @param array $parameters    Array of arguments (including wildcards).
 353           *    @param mixed $reference     Array reference placed in the map.
 354           *    @access public
 355           */
 356          function addReference($parameters, $reference) {
 357              $place = count($this->_map);
 358              $this->_map[$place] = array();
 359              $this->_map[$place]["params"] = new ParametersExpectation($parameters);
 360              $this->_map[$place]["content"] = $reference;
 361          }
 362  
 363          /**
 364           *    Searches the call list for a matching parameter
 365           *    set. Returned by reference.
 366           *    @param array $parameters    Parameters to search by
 367           *                                without wildcards.
 368           *    @return object              Object held in the first matching
 369           *                                slot, otherwise null.
 370           *    @access public
 371           */
 372          function &findFirstMatch($parameters) {
 373              $slot = $this->_findFirstSlot($parameters);
 374              if (!isset($slot)) {
 375                  $null = null;
 376                  return $null;
 377              }
 378              return $slot["content"];
 379          }
 380  
 381          /**
 382           *    Searches the call list for a matching parameter
 383           *    set. True if successful.
 384           *    @param array $parameters    Parameters to search by
 385           *                                without wildcards.
 386           *    @return boolean             True if a match is present.
 387           *    @access public
 388           */
 389          function isMatch($parameters) {
 390              return ($this->_findFirstSlot($parameters) != null);
 391          }
 392  
 393          /**
 394           *    Searches the map for a matching item.
 395           *    @param array $parameters    Parameters to search by
 396           *                                without wildcards.
 397           *    @return array               Reference to slot or null.
 398           *    @access private
 399           */
 400          function &_findFirstSlot($parameters) {
 401              $count = count($this->_map);
 402              for ($i = 0; $i < $count; $i++) {
 403                  if ($this->_map[$i]["params"]->test($parameters)) {
 404                      return $this->_map[$i];
 405                  }
 406              }
 407              $null = null;
 408              return $null;
 409          }
 410      }
 411  
 412      /**
 413       *    An empty collection of methods that can have their
 414       *    return values set and expectations made of the
 415       *    calls upon them. The mock will assert the
 416       *    expectations against it's attached test case in
 417       *    addition to the server stub behaviour.
 418       *    @package SimpleTest
 419       *    @subpackage MockObjects
 420       */
 421      class SimpleMock {
 422          protected $_wildcard = MOCK_ANYTHING;
 423          protected $_is_strict = true;
 424          protected $_returns;
 425          protected $_return_sequence;
 426          protected $_call_counts;
 427          protected $_expected_counts;
 428          protected $_max_counts;
 429          protected $_expected_args;
 430          protected $_expected_args_at;
 431  
 432          /**
 433           *    Creates an empty return list and expectation list.
 434           *    All call counts are set to zero.
 435           *    @param SimpleTestCase $test    Test case to test expectations in.
 436           *    @param mixed $wildcard         Parameter matching wildcard.
 437           *    @param boolean $is_strict      Enables method name checks on
 438           *                                   expectations.
 439           */
 440          function SimpleMock() {
 441              $this->_returns = array();
 442              $this->_return_sequence = array();
 443              $this->_call_counts = array();
 444              $test = $this->_getCurrentTestCase();
 445              $test->tell($this);
 446              $this->_expected_counts = array();
 447              $this->_max_counts = array();
 448              $this->_expected_args = array();
 449              $this->_expected_args_at = array();
 450          }
 451  
 452          /**
 453           *    Disables a name check when setting expectations.
 454           *    This hack is needed for the partial mocks.
 455           *    @access public
 456           */
 457          function disableExpectationNameChecks() {
 458              $this->_is_strict = false;
 459          }
 460  
 461          /**
 462           *    Changes the default wildcard object.
 463           *    @param mixed $wildcard         Parameter matching wildcard.
 464           *    @access public
 465           */
 466          function setWildcard($wildcard) {
 467              $this->_wildcard = $wildcard;
 468          }
 469  
 470          /**
 471           *    Finds currently running test.
 472           *    @return SimpeTestCase    Current test case.
 473           *    @access protected
 474           */
 475          function &_getCurrentTestCase() {
 476              return SimpleTest::getCurrent();
 477          }
 478  
 479          /**
 480           *    Die if bad arguments array is passed
 481           *    @param mixed $args     The arguments value to be checked.
 482           *    @param string $task    Description of task attempt.
 483           *    @return boolean        Valid arguments
 484           *    @access private
 485           */
 486          function _checkArgumentsIsArray($args, $task) {
 487              if (! is_array($args)) {
 488                  trigger_error(
 489                      "Cannot $task as \$args parameter is not an array",
 490                      E_USER_ERROR);
 491              }
 492          }
 493  
 494          /**
 495           *    Triggers a PHP error if the method is not part
 496           *    of this object.
 497           *    @param string $method        Name of method.
 498           *    @param string $task          Description of task attempt.
 499           *    @access protected
 500           */
 501          function _dieOnNoMethod($method, $task) {
 502              if ($this->_is_strict && ! method_exists($this, $method)) {
 503                  trigger_error(
 504                          "Cannot $task as no $method}() in class " . get_class($this),
 505                          E_USER_ERROR);
 506              }
 507          }
 508  
 509          /**
 510           *    Replaces wildcard matches with wildcard
 511           *    expectations in the argument list.
 512           *    @param array $args      Raw argument list.
 513           *    @return array           Argument list with
 514           *                            expectations.
 515           *    @access private
 516           */
 517          function _replaceWildcards($args) {
 518              if ($args === false) {
 519                  return false;
 520              }
 521              for ($i = 0; $i < count($args); $i++) {
 522                  if ($args[$i] === $this->_wildcard) {
 523                      $args[$i] = new AnythingExpectation();
 524                  }
 525              }
 526              return $args;
 527          }
 528  
 529          /**
 530           *    Adds one to the call count of a method.
 531           *    @param string $method        Method called.
 532           *    @param array $args           Arguments as an array.
 533           *    @access protected
 534           */
 535          function _addCall($method, $args) {
 536              if (!isset($this->_call_counts[$method])) {
 537                  $this->_call_counts[$method] = 0;
 538              }
 539              $this->_call_counts[$method]++;
 540          }
 541  
 542          /**
 543           *    Fetches the call count of a method so far.
 544           *    @param string $method        Method name called.
 545           *    @return                      Number of calls so far.
 546           *    @access public
 547           */
 548          function getCallCount($method) {
 549              $this->_dieOnNoMethod($method, "get call count");
 550              $method = strtolower($method);
 551              if (! isset($this->_call_counts[$method])) {
 552                  return 0;
 553              }
 554              return $this->_call_counts[$method];
 555          }
 556  
 557          /**
 558           *    Sets a return for a parameter list that will
 559           *    be passed by value for all calls to this method.
 560           *    @param string $method       Method name.
 561           *    @param mixed $value         Result of call passed by value.
 562           *    @param array $args          List of parameters to match
 563           *                                including wildcards.
 564           *    @access public
 565           */
 566          function setReturnValue($method, $value, $args = false) {
 567              $this->_dieOnNoMethod($method, "set return value");
 568              $args = $this->_replaceWildcards($args);
 569              $method = strtolower($method);
 570              if (! isset($this->_returns[$method])) {
 571                  $this->_returns[$method] = new CallMap();
 572              }
 573              $this->_returns[$method]->addValue($args, $value);
 574          }
 575  
 576          /**
 577           *    Sets a return for a parameter list that will
 578           *    be passed by value only when the required call count
 579           *    is reached.
 580           *    @param integer $timing   Number of calls in the future
 581           *                             to which the result applies. If
 582           *                             not set then all calls will return
 583           *                             the value.
 584           *    @param string $method    Method name.
 585           *    @param mixed $value      Result of call passed by value.
 586           *    @param array $args       List of parameters to match
 587           *                             including wildcards.
 588           *    @access public
 589           */
 590          function setReturnValueAt($timing, $method, $value, $args = false) {
 591              $this->_dieOnNoMethod($method, "set return value sequence");
 592              $args = $this->_replaceWildcards($args);
 593              $method = strtolower($method);
 594              if (! isset($this->_return_sequence[$method])) {
 595                  $this->_return_sequence[$method] = array();
 596              }
 597              if (! isset($this->_return_sequence[$method][$timing])) {
 598                  $this->_return_sequence[$method][$timing] = new CallMap();
 599              }
 600              $this->_return_sequence[$method][$timing]->addValue($args, $value);
 601          }
 602  
 603          /**
 604           *    Sets a return for a parameter list that will
 605           *    be passed by reference for all calls.
 606           *    @param string $method       Method name.
 607           *    @param mixed $reference     Result of the call will be this object.
 608           *    @param array $args          List of parameters to match
 609           *                                including wildcards.
 610           *    @access public
 611           */
 612          function setReturnReference($method, $reference, $args = false) {
 613              $this->_dieOnNoMethod($method, "set return reference");
 614              $args = $this->_replaceWildcards($args);
 615              $method = strtolower($method);
 616              if (! isset($this->_returns[$method])) {
 617                  $this->_returns[$method] = new CallMap();
 618              }
 619              $this->_returns[$method]->addReference($args, $reference);
 620          }
 621  
 622          /**
 623           *    Sets a return for a parameter list that will
 624           *    be passed by value only when the required call count
 625           *    is reached.
 626           *    @param integer $timing    Number of calls in the future
 627           *                              to which the result applies. If
 628           *                              not set then all calls will return
 629           *                              the value.
 630           *    @param string $method     Method name.
 631           *    @param mixed $reference   Result of the call will be this object.
 632           *    @param array $args        List of parameters to match
 633           *                              including wildcards.
 634           *    @access public
 635           */
 636          function setReturnReferenceAt($timing, $method, $reference, $args = false) {
 637              $this->_dieOnNoMethod($method, "set return reference sequence");
 638              $args = $this->_replaceWildcards($args);
 639              $method = strtolower($method);
 640              if (! isset($this->_return_sequence[$method])) {
 641                  $this->_return_sequence[$method] = array();
 642              }
 643              if (! isset($this->_return_sequence[$method][$timing])) {
 644                  $this->_return_sequence[$method][$timing] = new CallMap();
 645              }
 646              $this->_return_sequence[$method][$timing]->addReference($args, $reference);
 647          }
 648  
 649          /**
 650           *    Sets up an expected call with a set of
 651           *    expected parameters in that call. All
 652           *    calls will be compared to these expectations
 653           *    regardless of when the call is made.
 654           *    @param string $method        Method call to test.
 655           *    @param array $args           Expected parameters for the call
 656           *                                 including wildcards.
 657           *    @param string $message       Overridden message.
 658           *    @access public
 659           */
 660          function expect($method, $args, $message = '%s') {
 661              $this->_dieOnNoMethod($method, 'set expected arguments');
 662              $this->_checkArgumentsIsArray($args, 'set expected arguments');
 663              $args = $this->_replaceWildcards($args);
 664              $message .= Mock::getExpectationLine();
 665              $this->_expected_args[strtolower($method)] =
 666                      new ParametersExpectation($args, $message);
 667          }
 668  
 669          /**
 670           *    @deprecated
 671           */
 672          function expectArguments($method, $args, $message = '%s') {
 673              return $this->expect($method, $args, $message);
 674          }
 675  
 676          /**
 677           *    Sets up an expected call with a set of
 678           *    expected parameters in that call. The
 679           *    expected call count will be adjusted if it
 680           *    is set too low to reach this call.
 681           *    @param integer $timing    Number of calls in the future at
 682           *                              which to test. Next call is 0.
 683           *    @param string $method     Method call to test.
 684           *    @param array $args        Expected parameters for the call
 685           *                              including wildcards.
 686           *    @param string $message    Overridden message.
 687           *    @access public
 688           */
 689          function expectAt($timing, $method, $args, $message = '%s') {
 690              $this->_dieOnNoMethod($method, 'set expected arguments at time');
 691              $this->_checkArgumentsIsArray($args, 'set expected arguments at time');
 692              $args = $this->_replaceWildcards($args);
 693              if (! isset($this->_expected_args_at[$timing])) {
 694                  $this->_expected_args_at[$timing] = array();
 695              }
 696              $method = strtolower($method);
 697              $message .= Mock::getExpectationLine();
 698              $this->_expected_args_at[$timing][$method] =
 699                      new ParametersExpectation($args, $message);
 700          }
 701  
 702          /**
 703           *    @deprecated
 704           */
 705          function expectArgumentsAt($timing, $method, $args, $message = '%s') {
 706              return $this->expectAt($timing, $method, $args, $message);
 707          }
 708  
 709          /**
 710           *    Sets an expectation for the number of times
 711           *    a method will be called. The tally method
 712           *    is used to check this.
 713           *    @param string $method        Method call to test.
 714           *    @param integer $count        Number of times it should
 715           *                                 have been called at tally.
 716           *    @param string $message       Overridden message.
 717           *    @access public
 718           */
 719          function expectCallCount($method, $count, $message = '%s') {
 720              $this->_dieOnNoMethod($method, 'set expected call count');
 721              $message .= Mock::getExpectationLine();
 722              $this->_expected_counts[strtolower($method)] =
 723                      new CallCountExpectation($method, $count, $message);
 724          }
 725  
 726          /**
 727           *    Sets the number of times a method may be called
 728           *    before a test failure is triggered.
 729           *    @param string $method        Method call to test.
 730           *    @param integer $count        Most number of times it should
 731           *                                 have been called.
 732           *    @param string $message       Overridden message.
 733           *    @access public
 734           */
 735          function expectMaximumCallCount($method, $count, $message = '%s') {
 736              $this->_dieOnNoMethod($method, 'set maximum call count');
 737              $message .= Mock::getExpectationLine();
 738              $this->_max_counts[strtolower($method)] =
 739                      new MaximumCallCountExpectation($method, $count, $message);
 740          }
 741  
 742          /**
 743           *    Sets the number of times to call a method to prevent
 744           *    a failure on the tally.
 745           *    @param string $method      Method call to test.
 746           *    @param integer $count      Least number of times it should
 747           *                               have been called.
 748           *    @param string $message     Overridden message.
 749           *    @access public
 750           */
 751          function expectMinimumCallCount($method, $count, $message = '%s') {
 752              $this->_dieOnNoMethod($method, 'set minimum call count');
 753              $message .= Mock::getExpectationLine();
 754              $this->_expected_counts[strtolower($method)] =
 755                      new MinimumCallCountExpectation($method, $count, $message);
 756          }
 757  
 758          /**
 759           *    Convenience method for barring a method
 760           *    call.
 761           *    @param string $method        Method call to ban.
 762           *    @param string $message       Overridden message.
 763           *    @access public
 764           */
 765          function expectNever($method, $message = '%s') {
 766              $this->expectMaximumCallCount($method, 0, $message);
 767          }
 768  
 769          /**
 770           *    Convenience method for a single method
 771           *    call.
 772           *    @param string $method     Method call to track.
 773           *    @param array $args        Expected argument list or
 774           *                              false for any arguments.
 775           *    @param string $message    Overridden message.
 776           *    @access public
 777           */
 778          function expectOnce($method, $args = false, $message = '%s') {
 779              $this->expectCallCount($method, 1, $message);
 780              if ($args !== false) {
 781                  $this->expectArguments($method, $args, $message);
 782              }
 783          }
 784  
 785          /**
 786           *    Convenience method for requiring a method
 787           *    call.
 788           *    @param string $method       Method call to track.
 789           *    @param array $args          Expected argument list or
 790           *                                false for any arguments.
 791           *    @param string $message      Overridden message.
 792           *    @access public
 793           */
 794          function expectAtLeastOnce($method, $args = false, $message = '%s') {
 795              $this->expectMinimumCallCount($method, 1, $message);
 796              if ($args !== false) {
 797                  $this->expectArguments($method, $args, $message);
 798              }
 799          }
 800  
 801          /**
 802           *    @deprecated
 803           */
 804          function tally() {
 805          }
 806  
 807          /**
 808           *    Receives event from unit test that the current
 809           *    test method has finished. Totals up the call
 810           *    counts and triggers a test assertion if a test
 811           *    is present for expected call counts.
 812           *    @param string $method    Current method name.
 813           *    @access public
 814           */
 815          function atTestEnd($method) {
 816              foreach ($this->_expected_counts as $method => $expectation) {
 817                  $this->_assertTrue(
 818                          $expectation->test($this->getCallCount($method)),
 819                          $expectation->overlayMessage($this->getCallCount($method)));
 820              }
 821              foreach ($this->_max_counts as $method => $expectation) {
 822                  if ($expectation->test($this->getCallCount($method))) {
 823                      $this->_assertTrue(
 824                              true,
 825                              $expectation->overlayMessage($this->getCallCount($method)));
 826                  }
 827              }
 828          }
 829  
 830          /**
 831           *    Returns the expected value for the method name
 832           *    and checks expectations. Will generate any
 833           *    test assertions as a result of expectations
 834           *    if there is a test present.
 835           *    @param string $method       Name of method to simulate.
 836           *    @param array $args          Arguments as an array.
 837           *    @return mixed               Stored return.
 838           *    @access private
 839           */
 840          function &_invoke($method, $args) {
 841              $method = strtolower($method);
 842              $step = $this->getCallCount($method);
 843              $this->_addCall($method, $args);
 844              $this->_checkExpectations($method, $args, $step);
 845              $result = $this->_getReturn($method, $args, $step);
 846              return $result;
 847          }
 848          /**
 849           *    Finds the return value matching the incoming
 850           *    arguments. If there is no matching value found
 851           *    then an error is triggered.
 852           *    @param string $method      Method name.
 853           *    @param array $args         Calling arguments.
 854           *    @param integer $step       Current position in the
 855           *                               call history.
 856           *    @return mixed              Stored return.
 857           *    @access protected
 858           */
 859          function &_getReturn($method, $args, $step) {
 860              if (isset($this->_return_sequence[$method][$step])) {
 861                  if ($this->_return_sequence[$method][$step]->isMatch($args)) {
 862                      $result = $this->_return_sequence[$method][$step]->findFirstMatch($args);
 863                      return $result;
 864                  }
 865              }
 866              if (isset($this->_returns[$method])) {
 867                  $result = $this->_returns[$method]->findFirstMatch($args);
 868                  return $result;
 869              }
 870              $null = null;
 871              return $null;
 872          }
 873  
 874          /**
 875           *    Tests the arguments against expectations.
 876           *    @param string $method        Method to check.
 877           *    @param array $args           Argument list to match.
 878           *    @param integer $timing       The position of this call
 879           *                                 in the call history.
 880           *    @access private
 881           */
 882          function _checkExpectations($method, $args, $timing) {
 883              if (isset($this->_max_counts[$method])) {
 884                  if (! $this->_max_counts[$method]->test($timing + 1)) {
 885                      $this->_assertTrue(
 886                              false,
 887                              $this->_max_counts[$method]->overlayMessage($timing + 1));
 888                  }
 889              }
 890              if (isset($this->_expected_args_at[$timing][$method])) {
 891                  $this->_assertTrue(
 892                          $this->_expected_args_at[$timing][$method]->test($args),
 893                          "Mock method [$method] at [$timing] -> " .
 894                                  $this->_expected_args_at[$timing][$method]->overlayMessage($args));
 895              } elseif (isset($this->_expected_args[$method])) {
 896                  $this->_assertTrue(
 897                          $this->_expected_args[$method]->test($args),
 898                          "Mock method [$method] -> " . $this->_expected_args[$method]->overlayMessage($args));
 899              }
 900          }
 901  
 902          /**
 903           *    Triggers an assertion on the held test case.
 904           *    Should be overridden when using another test
 905           *    framework other than the SimpleTest one if the
 906           *    assertion method has a different name.
 907           *    @param boolean $assertion     True will pass.
 908           *    @param string $message        Message that will go with
 909           *                                  the test event.
 910           *    @access protected
 911           */
 912          function _assertTrue($assertion, $message) {
 913              $test = $this->_getCurrentTestCase();
 914              $test->assertTrue($assertion, $message);
 915          }
 916      }
 917  
 918      /**
 919       *    Static methods only service class for code generation of
 920       *    mock objects.
 921       *    @package SimpleTest
 922       *    @subpackage MockObjects
 923       */
 924      class Mock {
 925  
 926          /**
 927           *    Factory for mock object classes.
 928           *    @access public
 929           */
 930          function Mock() {
 931              trigger_error('Mock factory methods are class only.');
 932          }
 933  
 934          /**
 935           *    Clones a class' interface and creates a mock version
 936           *    that can have return values and expectations set.
 937           *    @param string $class         Class to clone.
 938           *    @param string $mock_class    New class name. Default is
 939           *                                 the old name with "Mock"
 940           *                                 prepended.
 941           *    @param array $methods        Additional methods to add beyond
 942           *                                 those in th cloned class. Use this
 943           *                                 to emulate the dynamic addition of
 944           *                                 methods in the cloned class or when
 945           *                                 the class hasn't been written yet.
 946           *    @static
 947           *    @access public
 948           */
 949          static function generate($class, $mock_class = false, $methods = false) {
 950              $generator = new MockGenerator($class, $mock_class);
 951              return $generator->generate($methods);
 952          }
 953  
 954          /**
 955           *    Generates a version of a class with selected
 956           *    methods mocked only. Inherits the old class
 957           *    and chains the mock methods of an aggregated
 958           *    mock object.
 959           *    @param string $class            Class to clone.
 960           *    @param string $mock_class       New class name.
 961           *    @param array $methods           Methods to be overridden
 962           *                                    with mock versions.
 963           *    @static
 964           *    @access public
 965           */
 966          static function generatePartial($class, $mock_class, $methods) {
 967              $generator = new MockGenerator($class, $mock_class);
 968              return $generator->generatePartial($methods);
 969          }
 970  
 971          /**
 972           *    Uses a stack trace to find the line of an assertion.
 973           *    @param array $stack      Stack frames top most first. Only
 974           *                             needed if not using the PHP
 975           *                             backtrace function.
 976           *    @return string           Location of first expect*
 977           *                             method embedded in format string.
 978           *    @access public
 979           *    @static
 980           */
 981          static function getExpectationLine($stack = false) {
 982              if ($stack === false) {
 983                  $stack = SimpleTestCompatibility::getStackTrace();
 984              }
 985              return SimpleDumper::getFormattedAssertionLine($stack);
 986          }
 987      }
 988  
 989      /**
 990       *    @deprecated
 991       */
 992      class Stub extends Mock {
 993      }
 994  
 995      /**
 996       *    Service class for code generation of mock objects.
 997       *    @package SimpleTest
 998       *    @subpackage MockObjects
 999       */
1000      class MockGenerator {
1001          protected $_class;
1002          protected $_mock_class;
1003          protected $_mock_base;
1004          protected $_reflection;
1005  
1006          function MockGenerator($class, $mock_class) {
1007              $this->_class = $class;
1008              $this->_mock_class = $mock_class;
1009              $this->_mock_base = SimpleTest::getMockBaseClass();
1010              $this->_reflection = new SimpleReflection($this->_class);
1011          }
1012  
1013          /**
1014           *    Clones a class' interface and creates a mock version
1015           *    that can have return values and expectations set.
1016           *    @param array $methods        Additional methods to add beyond
1017           *                                 those in th cloned class. Use this
1018           *                                 to emulate the dynamic addition of
1019           *                                 methods in the cloned class or when
1020           *                                 the class hasn't been written yet.
1021           *    @access public
1022           */
1023          function generate($methods) {
1024              if (! $this->_reflection->classOrInterfaceExists()) {
1025                  return false;
1026              }
1027              if (! $this->_mock_class) {
1028                  $this->_mock_class = 'Mock' . $this->_class;
1029              }
1030              $mock_reflection = new SimpleReflection($this->_mock_class);
1031              if ($mock_reflection->classExistsSansAutoload()) {
1032                  return false;
1033              }
1034              return eval(
1035                      $this->_createClassCode($methods ? $methods : array()) .
1036                      " return true;");
1037          }
1038  
1039          /**
1040           *    Generates a version of a class with selected
1041           *    methods mocked only. Inherits the old class
1042           *    and chains the mock methods of an aggregated
1043           *    mock object.
1044           *    @param array $methods           Methods to be overridden
1045           *                                    with mock versions.
1046           *    @access public
1047           */
1048          function generatePartial($methods) {
1049              if (! $this->_reflection->classExists($this->_class)) {
1050                  return false;
1051              }
1052              $mock_reflection = new SimpleReflection($this->_mock_class);
1053              if ($mock_reflection->classExistsSansAutoload()) {
1054                  trigger_error("Partial mock class [$mock_class] already exists");
1055                  return false;
1056              }
1057              return eval($this->_extendClassCode($methods));
1058          }
1059  
1060          /**
1061           *    The new mock class code as a string.
1062           *    @param array $methods          Additional methods.
1063           *    @return string                 Code for new mock class.
1064           *    @access private
1065           */
1066          function _createClassCode($methods) {
1067              $implements = '';
1068              $interfaces = $this->_reflection->getInterfaces();
1069              if (function_exists('spl_classes')) {
1070                  $interfaces = array_diff($interfaces, array('Traversable'));
1071              }
1072              if (count($interfaces) > 0) {
1073                  $implements = 'implements ' . implode(', ', $interfaces);
1074              }
1075              $code = "class " . $this->_mock_class . " extends " . $this->_mock_base . " $implements {\n";
1076              $code .= "    function " . $this->_mock_class . "() {\n";
1077              $code .= "        \$this->" . $this->_mock_base . "();\n";
1078              $code .= "    }\n";
1079              $code .= $this->_createHandlerCode($methods);
1080              $code .= "}\n";
1081              return $code;
1082          }
1083  
1084          /**
1085           *    The extension class code as a string. The class
1086           *    composites a mock object and chains mocked methods
1087           *    to it.
1088           *    @param array  $methods       Mocked methods.
1089           *    @return string               Code for a new class.
1090           *    @access private
1091           */
1092          function _extendClassCode($methods) {
1093              $code  = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
1094              $code .= "    var \$_mock;\n";
1095              $code .= $this->_addMethodList($methods);
1096              $code .= "\n";
1097              $code .= "    function " . $this->_mock_class . "() {\n";
1098              $code .= "        \$this->_mock = new " . $this->_mock_base . "();\n";
1099              $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
1100              $code .= "    }\n";
1101              $code .= $this->_chainMockReturns();
1102              $code .= $this->_chainMockExpectations();
1103              $code .= $this->_overrideMethods($methods);
1104              $code .= "}\n";
1105              return $code;
1106          }
1107  
1108          /**
1109           *    Creates code within a class to generate replaced
1110           *    methods. All methods call the _invoke() handler
1111           *    with the method name and the arguments in an
1112           *    array.
1113           *    @param array $methods    Additional methods.
1114           *    @access private
1115           */
1116          function _createHandlerCode($methods) {
1117              $code = '';
1118              $methods = array_merge($methods, $this->_reflection->getMethods());
1119              foreach ($methods as $method) {
1120                  if ($this->_isConstructor($method)) {
1121                      continue;
1122                  }
1123                  $mock_reflection = new SimpleReflection($this->_mock_base);
1124                  if (in_array($method, $mock_reflection->getMethods())) {
1125                      continue;
1126                  }
1127                  $code .= "    " . $this->_reflection->getSignature($method) . " {\n";
1128                  $code .= "        \$args = func_get_args();\n";
1129                  $code .= "        \$result = &\$this->_invoke(\"$method\", \$args);\n";
1130                  $code .= "        return \$result;\n";
1131                  $code .= "    }\n";
1132              }
1133              return $code;
1134          }
1135  
1136          /**
1137           *    Tests to see if a special PHP method is about to
1138           *    be stubbed by mistake.
1139           *    @param string $method    Method name.
1140           *    @return boolean          True if special.
1141           *    @access private
1142           */
1143          function _isConstructor($method) {
1144              return in_array(
1145                      strtolower($method),
1146                      array('__construct', '__destruct', '__clone'));
1147          }
1148  
1149          /**
1150           *    Creates a list of mocked methods for error checking.
1151           *    @param array $methods       Mocked methods.
1152           *    @return string              Code for a method list.
1153           *    @access private
1154           */
1155          function _addMethodList($methods) {
1156              return "    var \$_mocked_methods = array('" . implode("', '", $methods) . "');\n";
1157          }
1158  
1159          /**
1160           *    Creates code to abandon the expectation if not mocked.
1161           *    @param string $alias       Parameter name of method name.
1162           *    @return string             Code for bail out.
1163           *    @access private
1164           */
1165          function _bailOutIfNotMocked($alias) {
1166              $code  = "        if (! in_array($alias, \$this->_mocked_methods)) {\n";
1167              $code .= "            trigger_error(\"Method [$alias] is not mocked\");\n";
1168              $code .= "            \$null = null;\n";
1169              $code .= "            return \$null;\n";
1170              $code .= "        }\n";
1171              return $code;
1172          }
1173  
1174          /**
1175           *    Creates source code for chaining to the composited
1176           *    mock object.
1177           *    @return string           Code for mock set up.
1178           *    @access private
1179           */
1180          function _chainMockReturns() {
1181              $code  = "    function setReturnValue(\$method, \$value, \$args = false) {\n";
1182              $code .= $this->_bailOutIfNotMocked("\$method");
1183              $code .= "        \$this->_mock->setReturnValue(\$method, \$value, \$args);\n";
1184              $code .= "    }\n";
1185              $code .= "    function setReturnValueAt(\$timing, \$method, \$value, \$args = false) {\n";
1186              $code .= $this->_bailOutIfNotMocked("\$method");
1187              $code .= "        \$this->_mock->setReturnValueAt(\$timing, \$method, \$value, \$args);\n";
1188              $code .= "    }\n";
1189              $code .= "    function setReturnReference(\$method, &\$ref, \$args = false) {\n";
1190              $code .= $this->_bailOutIfNotMocked("\$method");
1191              $code .= "        \$this->_mock->setReturnReference(\$method, \$ref, \$args);\n";
1192              $code .= "    }\n";
1193              $code .= "    function setReturnReferenceAt(\$timing, \$method, &\$ref, \$args = false) {\n";
1194              $code .= $this->_bailOutIfNotMocked("\$method");
1195              $code .= "        \$this->_mock->setReturnReferenceAt(\$timing, \$method, \$ref, \$args);\n";
1196              $code .= "    }\n";
1197              return $code;
1198          }
1199  
1200          /**
1201           *    Creates source code for chaining to an aggregated
1202           *    mock object.
1203           *    @return string                 Code for expectations.
1204           *    @access private
1205           */
1206          function _chainMockExpectations() {
1207              $code  = "    function expect(\$method, \$args = false) {\n";
1208              $code .= $this->_bailOutIfNotMocked("\$method");
1209              $code .= "        \$this->_mock->expect(\$method, \$args);\n";
1210              $code .= "    }\n";
1211              $code .= "    function expectArguments(\$method, \$args = false) {\n";
1212              $code .= $this->_bailOutIfNotMocked("\$method");
1213              $code .= "        \$this->_mock->expectArguments(\$method, \$args);\n";
1214              $code .= "    }\n";
1215              $code .= "    function expectAt(\$timing, \$method, \$args = false) {\n";
1216              $code .= $this->_bailOutIfNotMocked("\$method");
1217              $code .= "        \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args);\n";
1218              $code .= "    }\n";
1219              $code .= "    function expectArgumentsAt(\$timing, \$method, \$args = false) {\n";
1220              $code .= $this->_bailOutIfNotMocked("\$method");
1221              $code .= "        \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args);\n";
1222              $code .= "    }\n";
1223              $code .= "    function expectCallCount(\$method, \$count) {\n";
1224              $code .= $this->_bailOutIfNotMocked("\$method");
1225              $code .= "        \$this->_mock->expectCallCount(\$method, \$count);\n";
1226              $code .= "    }\n";
1227              $code .= "    function expectMaximumCallCount(\$method, \$count) {\n";
1228              $code .= $this->_bailOutIfNotMocked("\$method");
1229              $code .= "        \$this->_mock->expectMaximumCallCount(\$method, \$count);\n";
1230              $code .= "    }\n";
1231              $code .= "    function expectMinimumCallCount(\$method, \$count) {\n";
1232              $code .= $this->_bailOutIfNotMocked("\$method");
1233              $code .= "        \$this->_mock->expectMinimumCallCount(\$method, \$count);\n";
1234              $code .= "    }\n";
1235              $code .= "    function expectNever(\$method) {\n";
1236              $code .= $this->_bailOutIfNotMocked("\$method");
1237              $code .= "        \$this->_mock->expectNever(\$method);\n";
1238              $code .= "    }\n";
1239              $code .= "    function expectOnce(\$method, \$args = false) {\n";
1240              $code .= $this->_bailOutIfNotMocked("\$method");
1241              $code .= "        \$this->_mock->expectOnce(\$method, \$args);\n";
1242              $code .= "    }\n";
1243              $code .= "    function expectAtLeastOnce(\$method, \$args = false) {\n";
1244              $code .= $this->_bailOutIfNotMocked("\$method");
1245              $code .= "        \$this->_mock->expectAtLeastOnce(\$method, \$args);\n";
1246              $code .= "    }\n";
1247              $code .= "    function tally() {\n";
1248              $code .= "        \$this->_mock->tally();\n";
1249              $code .= "    }\n";
1250              return $code;
1251          }
1252  
1253          /**
1254           *    Creates source code to override a list of methods
1255           *    with mock versions.
1256           *    @param array $methods    Methods to be overridden
1257           *                             with mock versions.
1258           *    @return string           Code for overridden chains.
1259           *    @access private
1260           */
1261          function _overrideMethods($methods) {
1262              $code = "";
1263              foreach ($methods as $method) {
1264                  $code .= "    " . $this->_reflection->getSignature($method) . " {\n";
1265                  $code .= "        \$args = func_get_args();\n";
1266                  $code .= "        \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
1267                  $code .= "        return \$result;\n";
1268                  $code .= "    }\n";
1269              }
1270              return $code;
1271          }
1272      }
1273  ?>


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7