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-2014 Pádraic Brady (http://blog.astrumfutura.com)
18: * @license http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
19: */
20:
21: namespace Mockery;
22:
23: class ExpectationDirector
24: {
25:
26: /**
27: * Method name the director is directing
28: *
29: * @var string
30: */
31: protected $_name = null;
32:
33: /**
34: * Mock object the director is attached to
35: *
36: * @var \Mockery\MockInterface
37: */
38: protected $_mock = null;
39:
40: /**
41: * Stores an array of all expectations for this mock
42: *
43: * @var array
44: */
45: protected $_expectations = array();
46:
47: /**
48: * The expected order of next call
49: *
50: * @var int
51: */
52: protected $_expectedOrder = null;
53:
54: /**
55: * Stores an array of all default expectations for this mock
56: *
57: * @var array
58: */
59: protected $_defaults = array();
60:
61: /**
62: * Constructor
63: *
64: * @param string $name
65: * @param \Mockery\MockInterface $mock
66: */
67: public function __construct($name, \Mockery\MockInterface $mock)
68: {
69: $this->_name = $name;
70: $this->_mock = $mock;
71: }
72:
73: /**
74: * Add a new expectation to the director
75: *
76: * @param Mutateme\Expectation $expectation
77: */
78: public function addExpectation(\Mockery\Expectation $expectation)
79: {
80: $this->_expectations[] = $expectation;
81: }
82:
83: /**
84: * Handle a method call being directed by this instance
85: *
86: * @param array $args
87: * @return mixed
88: */
89: public function call(array $args)
90: {
91: $expectation = $this->findExpectation($args);
92: if (is_null($expectation)) {
93: $exception = new \Mockery\Exception\NoMatchingExpectationException(
94: 'No matching handler found for '
95: . $this->_mock->mockery_getName() . '::'
96: . \Mockery::formatArgs($this->_name, $args)
97: . '. Either the method was unexpected or its arguments matched'
98: . ' no expected argument list for this method'
99: . PHP_EOL . PHP_EOL
100: . \Mockery::formatObjects($args)
101: );
102: $exception->setMock($this->_mock)
103: ->setMethodName($this->_name)
104: ->setActualArguments($args);
105: throw $exception;
106: }
107: return $expectation->verifyCall($args);
108: }
109:
110: /**
111: * Verify all expectations of the director
112: *
113: * @throws \Mockery\CountValidator\Exception
114: * @return void
115: */
116: public function verify()
117: {
118: if (!empty($this->_expectations)) {
119: foreach ($this->_expectations as $exp) {
120: $exp->verify();
121: }
122: } else {
123: foreach ($this->_defaults as $exp) {
124: $exp->verify();
125: }
126: }
127: }
128:
129: /**
130: * Attempt to locate an expectation matching the provided args
131: *
132: * @param array $args
133: * @return mixed
134: */
135: public function findExpectation(array $args)
136: {
137: if (!empty($this->_expectations)) {
138: return $this->_findExpectationIn($this->_expectations, $args);
139: } else {
140: return $this->_findExpectationIn($this->_defaults, $args);
141: }
142: }
143:
144: /**
145: * Make the given expectation a default for all others assuming it was
146: * correctly created last
147: *
148: * @param \Mockery\Expectation
149: */
150: public function makeExpectationDefault(\Mockery\Expectation $expectation)
151: {
152: $last = end($this->_expectations);
153: if ($last === $expectation) {
154: array_pop($this->_expectations);
155: array_unshift($this->_defaults, $expectation);
156: } else {
157: throw new \Mockery\Exception(
158: 'Cannot turn a previously defined expectation into a default'
159: );
160: }
161: }
162:
163: /**
164: * Search current array of expectations for a match
165: *
166: * @param array $expectations
167: * @param array $args
168: * @return mixed
169: */
170: protected function _findExpectationIn(array $expectations, array $args)
171: {
172: foreach ($expectations as $exp) {
173: if ($exp->matchArgs($args) && $exp->isEligible()) {
174: return $exp;
175: }
176: }
177: foreach ($expectations as $exp) {
178: if ($exp->matchArgs($args)) {
179: return $exp;
180: }
181: }
182: }
183:
184: /**
185: * Return all expectations assigned to this director
186: *
187: * @return array
188: */
189: public function getExpectations()
190: {
191: return $this->_expectations;
192: }
193:
194: /**
195: * Return the number of expectations assigned to this director.
196: *
197: * @return int
198: */
199: public function getExpectationCount()
200: {
201: return count($this->getExpectations());
202: }
203:
204: }
205: