Completed
Pull Request — master (#566)
by Thomas
04:26
created

ExpectationDirector::findExpectation()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

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