/library/Mockery/Mock.php

https://github.com/yugeon/mockery · PHP · 377 lines · 152 code · 34 blank · 191 comment · 10 complexity · 1f4a42233db917e8bab2acd6086e48a1 MD5 · raw file

  1. <?php
  2. /**
  3. * Mockery
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://github.com/padraic/mockery/blob/master/LICENSE
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to padraic@php.net so we can send you a copy immediately.
  14. *
  15. * @category Mockery
  16. * @package Mockery
  17. * @copyright Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com)
  18. * @license http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
  19. */
  20. namespace Mockery;
  21. class Mock implements MockInterface
  22. {
  23. /**
  24. * Stores an array of all expectation directors for this mock
  25. *
  26. * @var array
  27. */
  28. protected $_mockery_expectations = array();
  29. /**
  30. * Last expectation that was set
  31. *
  32. * @var object
  33. */
  34. protected $_mockery_lastExpectation = null;
  35. /**
  36. * Flag to indicate whether we can ignore method calls missing from our
  37. * expectations
  38. *
  39. * @var bool
  40. */
  41. protected $_mockery_ignoreMissing = false;
  42. /**
  43. * Flag to indicate whether this mock was verified
  44. *
  45. * @var bool
  46. */
  47. protected $_mockery_verified = false;
  48. /**
  49. * Given name of the mock
  50. *
  51. * @var string
  52. */
  53. protected $_mockery_name = null;
  54. /**
  55. * Order number of allocation
  56. *
  57. * @var int
  58. */
  59. protected $_mockery_allocatedOrder = 0;
  60. /**
  61. * Current ordered number
  62. *
  63. * @var int
  64. */
  65. protected $_mockery_currentOrder = 0;
  66. /**
  67. * Ordered groups
  68. *
  69. * @var array
  70. */
  71. protected $_mockery_groups = array();
  72. /**
  73. * Mock container containing this mock object
  74. *
  75. * @var \Mockery\Container
  76. */
  77. protected $_mockery_container = null;
  78. /**
  79. * Instance of a core object on which methods are called in the event
  80. * it has been set, and an expectation for one of the object's methods
  81. * does not exist. This implements a simple partial mock proxy system.
  82. *
  83. * @var object
  84. */
  85. protected $_mockery_partial = null;
  86. /**
  87. * Flag to indicate we should ignore all expectations temporarily. Used
  88. * mainly to prevent expectation matching when in the middle of a mock
  89. * object recording session.
  90. *
  91. * @var bool
  92. */
  93. protected $_mockery_disableExpectationMatching = false;
  94. /**
  95. * We want to avoid constructors since class is copied to Generator.php
  96. * for inclusion on extending class definitions.
  97. *
  98. * @param string $name
  99. * @param \Mockery\Container $container
  100. * @param object $partialObject
  101. * @return void
  102. */
  103. public function mockery_init($name, \Mockery\Container $container = null, $partialObject = null)
  104. {
  105. $this->_mockery_name = $name;
  106. if(is_null($container)) {
  107. $container = new \Mockery\Container;
  108. }
  109. $this->_mockery_container = $container;
  110. if (!is_null($partialObject)) {
  111. $this->_mockery_partial = $partialObject;
  112. }
  113. }
  114. /**
  115. * Set expected method calls
  116. *
  117. * @param mixed
  118. * @return \Mockery\Expectation
  119. */
  120. public function shouldReceive()
  121. {
  122. $self =& $this;
  123. $lastExpectation = \Mockery::parseShouldReturnArgs(
  124. $this, func_get_args(), function($method) use ($self) {
  125. $director = $self->mockery_getExpectationsFor($method);
  126. if (!$director) {
  127. $director = new \Mockery\ExpectationDirector($method, $self);
  128. $self->mockery_setExpectationsFor($method, $director);
  129. }
  130. $expectation = new \Mockery\Expectation($self, $method);
  131. $director->addExpectation($expectation);
  132. return $expectation;
  133. }
  134. );
  135. return $lastExpectation;
  136. }
  137. /**
  138. * Set mock to ignore unexpected methods and return Undefined class
  139. *
  140. * @return void
  141. */
  142. public function shouldIgnoreMissing()
  143. {
  144. $this->_mockery_ignoreMissing = true;
  145. }
  146. /**
  147. * Accepts a closure which is executed with an object recorder which proxies
  148. * to the partial source object. The intent being to record the
  149. * interactions of a concrete object as a set of expectations on the
  150. * current mock object. The partial may then be passed to a second process
  151. * to see if it fulfils the same (or exact same) contract as the original.
  152. *
  153. * @param Closure $closure
  154. */
  155. public function shouldExpect(Closure $closure)
  156. {
  157. $recorder = new \Mockery\Recorder($this, $this->_mockery_partial);
  158. $this->_mockery_disableExpectationMatching = true;
  159. $closure($recorder);
  160. $this->_mockery_disableExpectationMatching = false;
  161. return $this;
  162. }
  163. /**
  164. * In the event shouldReceive() accepting one or more methods/returns,
  165. * this method will switch them from normal expectations to default
  166. * expectations
  167. *
  168. * @return self
  169. */
  170. public function byDefault()
  171. {
  172. foreach ($this->_mockery_expectations as $director) {
  173. $exps = $director->getExpectations();
  174. foreach ($exps as $exp) {
  175. $exp->byDefault();
  176. }
  177. }
  178. return $this;
  179. }
  180. /**
  181. * Capture calls to this mock
  182. */
  183. public function __call($method, array $args)
  184. {
  185. if (isset($this->_mockery_expectations[$method])
  186. && !$this->_mockery_disableExpectationMatching) {
  187. $handler = $this->_mockery_expectations[$method];
  188. return $handler->call($args);
  189. } elseif (!is_null($this->_mockery_partial) && method_exists($this->_mockery_partial, $method)) {
  190. return call_user_func_array(array($this->_mockery_partial, $method), $args);
  191. } elseif ($this->_mockery_ignoreMissing) {
  192. $return = new \Mockery\Undefined;
  193. return $return;
  194. }
  195. throw new \BadMethodCallException(
  196. 'Method ' . $this->_mockery_name . '::' . $method . '() does not exist on this mock object'
  197. );
  198. }
  199. /**
  200. * Iterate across all expectation directors and validate each
  201. *
  202. * @throws \Mockery\CountValidator\Exception
  203. * @return void
  204. */
  205. public function mockery_verify()
  206. {
  207. if ($this->_mockery_verified) return true;
  208. $this->_mockery_verified = true;
  209. foreach($this->_mockery_expectations as $director) {
  210. $director->verify();
  211. }
  212. }
  213. /**
  214. * Tear down tasks for this mock
  215. *
  216. * @return void
  217. */
  218. public function mockery_teardown()
  219. {
  220. }
  221. /**
  222. * Fetch the next available allocation order number
  223. *
  224. * @return int
  225. */
  226. public function mockery_allocateOrder()
  227. {
  228. $this->_mockery_allocatedOrder += 1;
  229. return $this->_mockery_allocatedOrder;
  230. }
  231. /**
  232. * Set ordering for a group
  233. *
  234. * @param mixed $group
  235. * @param int $order
  236. */
  237. public function mockery_setGroup($group, $order)
  238. {
  239. $this->_mockery_groups[$group] = $order;
  240. }
  241. /**
  242. * Fetch array of ordered groups
  243. *
  244. * @return array
  245. */
  246. public function mockery_getGroups()
  247. {
  248. return $this->_mockery_groups;
  249. }
  250. /**
  251. * Set current ordered number
  252. *
  253. * @param int $order
  254. */
  255. public function mockery_setCurrentOrder($order)
  256. {
  257. $this->_mockery_currentOrder = $order;
  258. return $this->_mockery_currentOrder;
  259. }
  260. /**
  261. * Get current ordered number
  262. *
  263. * @return int
  264. */
  265. public function mockery_getCurrentOrder()
  266. {
  267. return $this->_mockery_currentOrder;
  268. }
  269. /**
  270. * Validate the current mock's ordering
  271. *
  272. * @param string $method
  273. * @param int $order
  274. * @throws \Mockery\Exception
  275. * @return void
  276. */
  277. public function mockery_validateOrder($method, $order)
  278. {
  279. if ($order < $this->_mockery_currentOrder) {
  280. throw new \Mockery\Exception(
  281. 'Method ' . $this->_mockery_name . '::' . $method . '()'
  282. . ' called out of order: expected order '
  283. . $order . ', was ' . $this->_mockery_currentOrder
  284. );
  285. }
  286. $this->mockery_setCurrentOrder($order);
  287. }
  288. /**
  289. * Return the expectations director for the given method
  290. *
  291. * @var string $method
  292. * @return \Mockery\ExpectationDirector|null
  293. */
  294. public function mockery_setExpectationsFor($method, \Mockery\ExpectationDirector $director)
  295. {
  296. $this->_mockery_expectations[$method] = $director;
  297. }
  298. /**
  299. * Return the expectations director for the given method
  300. *
  301. * @var string $method
  302. * @return \Mockery\ExpectationDirector|null
  303. */
  304. public function mockery_getExpectationsFor($method)
  305. {
  306. if (isset($this->_mockery_expectations[$method])) {
  307. return $this->_mockery_expectations[$method];
  308. }
  309. }
  310. /**
  311. * Find an expectation matching the given method and arguments
  312. *
  313. * @var string $method
  314. * @var array $args
  315. * @return \Mockery\Expectation|null
  316. */
  317. public function mockery_findExpectation($method, array $args)
  318. {
  319. if (!isset($this->_mockery_expectations[$method])) {
  320. return null;
  321. }
  322. $director = $this->_mockery_expectations[$method];
  323. return $director->findExpectation($args);
  324. }
  325. /**
  326. * Return the container for this mock
  327. *
  328. * @return \Mockery\Container
  329. */
  330. public function mockery_getContainer()
  331. {
  332. return $this->_mockery_container;
  333. }
  334. /**
  335. * Return the name for this mock
  336. *
  337. * @return string
  338. */
  339. public function mockery_getName()
  340. {
  341. return $this->_mockery_name;
  342. }
  343. }