1<?php 2 3/* 4 * This file is part of the Prophecy. 5 * (c) Konstantin Kudryashov <ever.zet@gmail.com> 6 * Marcello Duarte <marcello.duarte@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Prophecy; 13 14use Prophecy\Doubler\Doubler; 15use Prophecy\Doubler\LazyDouble; 16use Prophecy\Doubler\ClassPatch; 17use Prophecy\Prophecy\ObjectProphecy; 18use Prophecy\Prophecy\RevealerInterface; 19use Prophecy\Prophecy\Revealer; 20use Prophecy\Call\CallCenter; 21use Prophecy\Util\StringUtil; 22use Prophecy\Exception\Prediction\PredictionException; 23use Prophecy\Exception\Prediction\AggregateException; 24 25/** 26 * Prophet creates prophecies. 27 * 28 * @author Konstantin Kudryashov <ever.zet@gmail.com> 29 */ 30class Prophet 31{ 32 private $doubler; 33 private $revealer; 34 private $util; 35 36 /** 37 * @var ObjectProphecy[] 38 */ 39 private $prophecies = array(); 40 41 /** 42 * Initializes Prophet. 43 * 44 * @param null|Doubler $doubler 45 * @param null|RevealerInterface $revealer 46 * @param null|StringUtil $util 47 */ 48 public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null, 49 StringUtil $util = null) 50 { 51 if (null === $doubler) { 52 $doubler = new Doubler; 53 $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch); 54 $doubler->registerClassPatch(new ClassPatch\TraversablePatch); 55 $doubler->registerClassPatch(new ClassPatch\ThrowablePatch); 56 $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch); 57 $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch); 58 $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch); 59 $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch()); 60 $doubler->registerClassPatch(new ClassPatch\MagicCallPatch); 61 $doubler->registerClassPatch(new ClassPatch\KeywordPatch); 62 } 63 64 $this->doubler = $doubler; 65 $this->revealer = $revealer ?: new Revealer; 66 $this->util = $util ?: new StringUtil; 67 } 68 69 /** 70 * Creates new object prophecy. 71 * 72 * @param null|string $classOrInterface Class or interface name 73 * 74 * @return ObjectProphecy 75 */ 76 public function prophesize($classOrInterface = null) 77 { 78 $this->prophecies[] = $prophecy = new ObjectProphecy( 79 new LazyDouble($this->doubler), 80 new CallCenter($this->util), 81 $this->revealer 82 ); 83 84 if ($classOrInterface && class_exists($classOrInterface)) { 85 return $prophecy->willExtend($classOrInterface); 86 } 87 88 if ($classOrInterface && interface_exists($classOrInterface)) { 89 return $prophecy->willImplement($classOrInterface); 90 } 91 92 return $prophecy; 93 } 94 95 /** 96 * Returns all created object prophecies. 97 * 98 * @return ObjectProphecy[] 99 */ 100 public function getProphecies() 101 { 102 return $this->prophecies; 103 } 104 105 /** 106 * Returns Doubler instance assigned to this Prophet. 107 * 108 * @return Doubler 109 */ 110 public function getDoubler() 111 { 112 return $this->doubler; 113 } 114 115 /** 116 * Checks all predictions defined by prophecies of this Prophet. 117 * 118 * @throws Exception\Prediction\AggregateException If any prediction fails 119 */ 120 public function checkPredictions() 121 { 122 $exception = new AggregateException("Some predictions failed:\n"); 123 foreach ($this->prophecies as $prophecy) { 124 try { 125 $prophecy->checkProphecyMethodsPredictions(); 126 } catch (PredictionException $e) { 127 $exception->append($e); 128 } 129 } 130 131 if (count($exception->getExceptions())) { 132 throw $exception; 133 } 134 } 135} 136