PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/swiftmailer/swiftmailer/test-suite/lib/simpletest/mock_objects.php

https://github.com/DoveID/Laravel-Craft
PHP | 1630 lines | 769 code | 107 blank | 754 comment | 65 complexity | d0ddc25c0a387f00d4f6033c865907e7 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file