PageRenderTime 37ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php

https://gitlab.com/techniconline/kmc
PHP | 443 lines | 221 code | 51 blank | 171 comment | 18 complexity | 3c9e7af1c4ecf01e251918fbfdaac05f MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Prophecy.
  4. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5. * Marcello Duarte <marcello.duarte@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Prophecy\Prophecy;
  11. use Prophecy\Argument;
  12. use Prophecy\Prophet;
  13. use Prophecy\Promise;
  14. use Prophecy\Prediction;
  15. use Prophecy\Exception\Doubler\MethodNotFoundException;
  16. use Prophecy\Exception\InvalidArgumentException;
  17. use Prophecy\Exception\Prophecy\MethodProphecyException;
  18. /**
  19. * Method prophecy.
  20. *
  21. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  22. */
  23. class MethodProphecy
  24. {
  25. private $objectProphecy;
  26. private $methodName;
  27. private $argumentsWildcard;
  28. private $promise;
  29. private $prediction;
  30. private $checkedPredictions = array();
  31. private $bound = false;
  32. /**
  33. * Initializes method prophecy.
  34. *
  35. * @param ObjectProphecy $objectProphecy
  36. * @param string $methodName
  37. * @param null|Argument\ArgumentsWildcard|array $arguments
  38. *
  39. * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found
  40. */
  41. public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null)
  42. {
  43. $double = $objectProphecy->reveal();
  44. if (!method_exists($double, $methodName)) {
  45. throw new MethodNotFoundException(sprintf(
  46. 'Method `%s::%s()` is not defined.', get_class($double), $methodName
  47. ), get_class($double), $methodName, $arguments);
  48. }
  49. $this->objectProphecy = $objectProphecy;
  50. $this->methodName = $methodName;
  51. $reflectedMethod = new \ReflectionMethod($double, $methodName);
  52. if ($reflectedMethod->isFinal()) {
  53. throw new MethodProphecyException(sprintf(
  54. "Can not add prophecy for a method `%s::%s()`\n" .
  55. "as it is a final method.",
  56. get_class($double),
  57. $methodName
  58. ), $this);
  59. }
  60. if (null !== $arguments) {
  61. $this->withArguments($arguments);
  62. }
  63. if (version_compare(PHP_VERSION, '7.0', '>=') && true === $reflectedMethod->hasReturnType()) {
  64. $type = (string)$reflectedMethod->getReturnType();
  65. $this->will(function () use ($type) {
  66. switch ($type) {
  67. case 'string':
  68. return '';
  69. case 'float':
  70. return 0.0;
  71. case 'int':
  72. return 0;
  73. case 'bool':
  74. return false;
  75. case 'array':
  76. return array();
  77. case 'callable':
  78. case 'Closure':
  79. return function () {
  80. };
  81. case 'Traversable':
  82. case 'Generator':
  83. // Remove eval() when minimum version >=5.5
  84. $generator = eval('return function () { yield; };');
  85. return $generator();
  86. default:
  87. $prophet = new Prophet;
  88. return $prophet->prophesize($type)->reveal();
  89. }
  90. });
  91. }
  92. }
  93. /**
  94. * Sets argument wildcard.
  95. *
  96. * @param array|Argument\ArgumentsWildcard $arguments
  97. *
  98. * @return $this
  99. *
  100. * @throws \Prophecy\Exception\InvalidArgumentException
  101. */
  102. public function withArguments($arguments)
  103. {
  104. if (is_array($arguments)) {
  105. $arguments = new Argument\ArgumentsWildcard($arguments);
  106. }
  107. if (!$arguments instanceof Argument\ArgumentsWildcard) {
  108. throw new InvalidArgumentException(sprintf(
  109. "Either an array or an instance of ArgumentsWildcard expected as\n" .
  110. 'a `MethodProphecy::withArguments()` argument, but got %s.',
  111. gettype($arguments)
  112. ));
  113. }
  114. $this->argumentsWildcard = $arguments;
  115. return $this;
  116. }
  117. /**
  118. * Sets custom promise to the prophecy.
  119. *
  120. * @param callable|Promise\PromiseInterface $promise
  121. *
  122. * @return $this
  123. *
  124. * @throws \Prophecy\Exception\InvalidArgumentException
  125. */
  126. public function will($promise)
  127. {
  128. if (is_callable($promise)) {
  129. $promise = new Promise\CallbackPromise($promise);
  130. }
  131. if (!$promise instanceof Promise\PromiseInterface) {
  132. throw new InvalidArgumentException(sprintf(
  133. 'Expected callable or instance of PromiseInterface, but got %s.',
  134. gettype($promise)
  135. ));
  136. }
  137. $this->bindToObjectProphecy();
  138. $this->promise = $promise;
  139. return $this;
  140. }
  141. /**
  142. * Sets return promise to the prophecy.
  143. *
  144. * @see Prophecy\Promise\ReturnPromise
  145. *
  146. * @return $this
  147. */
  148. public function willReturn()
  149. {
  150. return $this->will(new Promise\ReturnPromise(func_get_args()));
  151. }
  152. /**
  153. * Sets return argument promise to the prophecy.
  154. *
  155. * @param int $index The zero-indexed number of the argument to return
  156. *
  157. * @see Prophecy\Promise\ReturnArgumentPromise
  158. *
  159. * @return $this
  160. */
  161. public function willReturnArgument($index = 0)
  162. {
  163. return $this->will(new Promise\ReturnArgumentPromise($index));
  164. }
  165. /**
  166. * Sets throw promise to the prophecy.
  167. *
  168. * @see Prophecy\Promise\ThrowPromise
  169. *
  170. * @param string|\Exception $exception Exception class or instance
  171. *
  172. * @return $this
  173. */
  174. public function willThrow($exception)
  175. {
  176. return $this->will(new Promise\ThrowPromise($exception));
  177. }
  178. /**
  179. * Sets custom prediction to the prophecy.
  180. *
  181. * @param callable|Prediction\PredictionInterface $prediction
  182. *
  183. * @return $this
  184. *
  185. * @throws \Prophecy\Exception\InvalidArgumentException
  186. */
  187. public function should($prediction)
  188. {
  189. if (is_callable($prediction)) {
  190. $prediction = new Prediction\CallbackPrediction($prediction);
  191. }
  192. if (!$prediction instanceof Prediction\PredictionInterface) {
  193. throw new InvalidArgumentException(sprintf(
  194. 'Expected callable or instance of PredictionInterface, but got %s.',
  195. gettype($prediction)
  196. ));
  197. }
  198. $this->bindToObjectProphecy();
  199. $this->prediction = $prediction;
  200. return $this;
  201. }
  202. /**
  203. * Sets call prediction to the prophecy.
  204. *
  205. * @see Prophecy\Prediction\CallPrediction
  206. *
  207. * @return $this
  208. */
  209. public function shouldBeCalled()
  210. {
  211. return $this->should(new Prediction\CallPrediction);
  212. }
  213. /**
  214. * Sets no calls prediction to the prophecy.
  215. *
  216. * @see Prophecy\Prediction\NoCallsPrediction
  217. *
  218. * @return $this
  219. */
  220. public function shouldNotBeCalled()
  221. {
  222. return $this->should(new Prediction\NoCallsPrediction);
  223. }
  224. /**
  225. * Sets call times prediction to the prophecy.
  226. *
  227. * @see Prophecy\Prediction\CallTimesPrediction
  228. *
  229. * @param $count
  230. *
  231. * @return $this
  232. */
  233. public function shouldBeCalledTimes($count)
  234. {
  235. return $this->should(new Prediction\CallTimesPrediction($count));
  236. }
  237. /**
  238. * Checks provided prediction immediately.
  239. *
  240. * @param callable|Prediction\PredictionInterface $prediction
  241. *
  242. * @return $this
  243. *
  244. * @throws \Prophecy\Exception\InvalidArgumentException
  245. */
  246. public function shouldHave($prediction)
  247. {
  248. if (is_callable($prediction)) {
  249. $prediction = new Prediction\CallbackPrediction($prediction);
  250. }
  251. if (!$prediction instanceof Prediction\PredictionInterface) {
  252. throw new InvalidArgumentException(sprintf(
  253. 'Expected callable or instance of PredictionInterface, but got %s.',
  254. gettype($prediction)
  255. ));
  256. }
  257. if (null === $this->promise) {
  258. $this->willReturn();
  259. }
  260. $calls = $this->getObjectProphecy()->findProphecyMethodCalls(
  261. $this->getMethodName(),
  262. $this->getArgumentsWildcard()
  263. );
  264. try {
  265. $prediction->check($calls, $this->getObjectProphecy(), $this);
  266. $this->checkedPredictions[] = $prediction;
  267. } catch (\Exception $e) {
  268. $this->checkedPredictions[] = $prediction;
  269. throw $e;
  270. }
  271. return $this;
  272. }
  273. /**
  274. * Checks call prediction.
  275. *
  276. * @see Prophecy\Prediction\CallPrediction
  277. *
  278. * @return $this
  279. */
  280. public function shouldHaveBeenCalled()
  281. {
  282. return $this->shouldHave(new Prediction\CallPrediction);
  283. }
  284. /**
  285. * Checks no calls prediction.
  286. *
  287. * @see Prophecy\Prediction\NoCallsPrediction
  288. *
  289. * @return $this
  290. */
  291. public function shouldNotHaveBeenCalled()
  292. {
  293. return $this->shouldHave(new Prediction\NoCallsPrediction);
  294. }
  295. /**
  296. * Checks no calls prediction.
  297. *
  298. * @see Prophecy\Prediction\NoCallsPrediction
  299. * @deprecated
  300. *
  301. * @return $this
  302. */
  303. public function shouldNotBeenCalled()
  304. {
  305. return $this->shouldNotHaveBeenCalled();
  306. }
  307. /**
  308. * Checks call times prediction.
  309. *
  310. * @see Prophecy\Prediction\CallTimesPrediction
  311. *
  312. * @param int $count
  313. *
  314. * @return $this
  315. */
  316. public function shouldHaveBeenCalledTimes($count)
  317. {
  318. return $this->shouldHave(new Prediction\CallTimesPrediction($count));
  319. }
  320. /**
  321. * Checks currently registered [with should(...)] prediction.
  322. */
  323. public function checkPrediction()
  324. {
  325. if (null === $this->prediction) {
  326. return;
  327. }
  328. $this->shouldHave($this->prediction);
  329. }
  330. /**
  331. * Returns currently registered promise.
  332. *
  333. * @return null|Promise\PromiseInterface
  334. */
  335. public function getPromise()
  336. {
  337. return $this->promise;
  338. }
  339. /**
  340. * Returns currently registered prediction.
  341. *
  342. * @return null|Prediction\PredictionInterface
  343. */
  344. public function getPrediction()
  345. {
  346. return $this->prediction;
  347. }
  348. /**
  349. * Returns predictions that were checked on this object.
  350. *
  351. * @return Prediction\PredictionInterface[]
  352. */
  353. public function getCheckedPredictions()
  354. {
  355. return $this->checkedPredictions;
  356. }
  357. /**
  358. * Returns object prophecy this method prophecy is tied to.
  359. *
  360. * @return ObjectProphecy
  361. */
  362. public function getObjectProphecy()
  363. {
  364. return $this->objectProphecy;
  365. }
  366. /**
  367. * Returns method name.
  368. *
  369. * @return string
  370. */
  371. public function getMethodName()
  372. {
  373. return $this->methodName;
  374. }
  375. /**
  376. * Returns arguments wildcard.
  377. *
  378. * @return Argument\ArgumentsWildcard
  379. */
  380. public function getArgumentsWildcard()
  381. {
  382. return $this->argumentsWildcard;
  383. }
  384. private function bindToObjectProphecy()
  385. {
  386. if ($this->bound) {
  387. return;
  388. }
  389. $this->getObjectProphecy()->addMethodProphecy($this);
  390. $this->bound = true;
  391. }
  392. }