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 :
21 : class Mockery
22 : {
23 : const BLOCKS = 'Mockery_Forward_Blocks';
24 :
25 : /**
26 : * Global container to hold all mocks for the current unit test running
27 : *
28 : * @var \Mockery\Container
29 : */
30 : protected static $_container = null;
31 :
32 : /**
33 : * Global configuration handler containing configuration options
34 : *
35 : * @var \Mockery\Configuration
36 : */
37 : protected static $_config = null;
38 :
39 : /**
40 : * Static shortcut to \Mockery\Container::mock()
41 : *
42 : * @return \Mockery\MockInterface
43 : */
44 : public static function mock()
45 : {
46 26 : if (is_null(self::$_container)) {
47 24 : self::$_container = new \Mockery\Container;
48 24 : }
49 26 : $args = func_get_args();
50 26 : return call_user_func_array(array(self::$_container, 'mock'), $args);
51 : }
52 :
53 : public static function instanceMock()
54 : {
55 0 : if (is_null(self::$_container)) {
56 0 : self::$_container = new \Mockery\Container;
57 0 : }
58 0 : $args = func_get_args();
59 0 : return call_user_func_array(array(self::$_container, 'instanceMock'), $args);
60 : }
61 :
62 : /**
63 : * Static shortcut to closing up and verifying all mocks in the global
64 : * container, and resetting the container static variable to null
65 : *
66 : * @return void
67 : */
68 : public static function close()
69 : {
70 66 : if (is_null(self::$_container)) return;
71 24 : self::$_container->mockery_teardown();
72 24 : self::$_container->mockery_close();
73 24 : self::$_container = null;
74 24 : }
75 :
76 : /**
77 : * Static fetching of a mock associated with a name or explicit class poser
78 : */
79 : public static function fetchMock($name)
80 : {
81 0 : return self::$_container->fetchMock($name);
82 : }
83 :
84 : /**
85 : * Get the container
86 : */
87 : public static function getContainer()
88 : {
89 0 : return self::$_container;
90 : }
91 :
92 : /**
93 : * Set the container
94 : */
95 : public static function setContainer(Mockery\Container $container)
96 : {
97 0 : return self::$_container = $container;
98 : }
99 :
100 : /**
101 : * Reset the container to NULL
102 : */
103 : public static function resetContainer()
104 : {
105 0 : self::$_container = null;
106 0 : }
107 :
108 : /**
109 : * Return instance of ANY matcher
110 : *
111 : * @return
112 : */
113 : public static function any()
114 : {
115 7 : $return = new \Mockery\Matcher\Any();
116 7 : return $return;
117 : }
118 :
119 : /**
120 : * Return instance of TYPE matcher
121 : *
122 : * @return
123 : */
124 : public static function type($expected)
125 : {
126 0 : $return = new \Mockery\Matcher\Type($expected);
127 0 : return $return;
128 : }
129 :
130 : /**
131 : * Return instance of DUCKTYPE matcher
132 : *
133 : * @return
134 : */
135 : public static function ducktype()
136 : {
137 0 : $return = new \Mockery\Matcher\Ducktype(func_get_args());
138 0 : return $return;
139 : }
140 :
141 : /**
142 : * Return instance of SUBSET matcher
143 : *
144 : * @return
145 : */
146 : public static function subset(array $part)
147 : {
148 0 : $return = new \Mockery\Matcher\Subset($part);
149 0 : return $return;
150 : }
151 :
152 : /**
153 : * Return instance of CONTAINS matcher
154 : *
155 : * @return
156 : */
157 : public static function contains()
158 : {
159 0 : $return = new \Mockery\Matcher\Contains(func_get_args());
160 0 : return $return;
161 : }
162 :
163 : /**
164 : * Return instance of HASKEY matcher
165 : *
166 : * @return
167 : */
168 : public static function hasKey($key)
169 : {
170 0 : $return = new \Mockery\Matcher\HasKey($key);
171 0 : return $return;
172 : }
173 :
174 : /**
175 : * Return instance of HASVALUE matcher
176 : *
177 : * @return
178 : */
179 : public static function hasValue($val)
180 : {
181 0 : $return = new \Mockery\Matcher\HasValue($val);
182 0 : return $return;
183 : }
184 :
185 : /**
186 : * Return instance of CLOSURE matcher
187 : *
188 : * @return
189 : */
190 : public static function on($closure)
191 : {
192 0 : $return = new \Mockery\Matcher\Closure($closure);
193 0 : return $return;
194 : }
195 :
196 : /**
197 : * Return instance of MUSTBE matcher
198 : *
199 : * @return
200 : */
201 : public static function mustBe($expected)
202 : {
203 0 : $return = new \Mockery\Matcher\MustBe($expected);
204 0 : return $return;
205 : }
206 :
207 : /**
208 : * Return instance of NOT matcher
209 : *
210 : * @return
211 : */
212 : public static function not($expected)
213 : {
214 0 : $return = new \Mockery\Matcher\Not($expected);
215 0 : return $return;
216 : }
217 :
218 : /**
219 : * Return instance of ANYOF matcher
220 : *
221 : * @return
222 : */
223 : public static function anyOf()
224 : {
225 0 : $return = new \Mockery\Matcher\AnyOf(func_get_args());
226 0 : return $return;
227 : }
228 :
229 : /**
230 : * Return instance of NOTANYOF matcher
231 : *
232 : * @return
233 : */
234 : public static function notAnyOf()
235 : {
236 0 : $return = new \Mockery\Matcher\NotAnyOf(func_get_args());
237 0 : return $return;
238 : }
239 :
240 : /**
241 : * Get the global configuration container
242 : */
243 : public static function getConfiguration()
244 : {
245 26 : if (is_null(self::$_config)) {
246 1 : self::$_config = new \Mockery\Configuration;
247 1 : }
248 26 : return self::$_config;
249 : }
250 :
251 : /**
252 : * Utility method to format method name and args into a string
253 : *
254 : * @param string $method
255 : * @param array $args
256 : * @return string
257 : */
258 : public static function formatArgs($method, array $args = null)
259 : {
260 0 : $return = $method . '(';
261 0 : if ($args && !empty($args)) {
262 0 : $parts = array();
263 0 : foreach($args as $arg) {
264 0 : if (is_object($arg)) {
265 0 : $parts[] = get_class($arg);
266 0 : } elseif (is_int($arg) || is_float($arg)) {
267 0 : $parts[] = $arg;
268 0 : } elseif (is_array($arg)) {
269 0 : $parts[] = 'Array';
270 0 : } else {
271 0 : $parts[] = '"' . (string) $arg . '"';
272 : }
273 0 : }
274 0 : $return .= implode(', ', $parts); // TODO: improve format
275 :
276 0 : }
277 0 : $return .= ')';
278 0 : return $return;
279 : }
280 :
281 : /**
282 : * Utility function to parse shouldReceive() arguments and generate
283 : * expectations from such as needed.
284 : *
285 : * @param \Mockery\MockInterface
286 : * @param array $args
287 : * @return \Mockery\CompositeExpectation
288 : */
289 : public static function parseShouldReturnArgs(\Mockery\MockInterface $mock, $args, $add)
290 : {
291 26 : $composite = new \Mockery\CompositeExpectation;
292 26 : foreach ($args as $arg) {
293 26 : if (is_array($arg)) {
294 0 : foreach($arg as $k=>$v) {
295 0 : $expectation = self::_buildDemeterChain($mock, $k, $add)->andReturn($v);
296 0 : $composite->add($expectation);
297 0 : }
298 26 : } elseif (is_string($arg)) {
299 26 : $expectation = self::_buildDemeterChain($mock, $arg, $add);
300 26 : $composite->add($expectation);
301 26 : }
302 26 : }
303 26 : return $composite;
304 : }
305 :
306 : /**
307 : * Sets up expectations on the members of the CompositeExpectation and
308 : * builds up any demeter chain that was passed to shouldReceive
309 : *
310 : * @param \Mockery\MockInterface $mock
311 : * @param string $arg
312 : * @param Closure $add
313 : * @return \Mockery\ExpectationDirector
314 : */
315 : protected static function _buildDemeterChain(\Mockery\MockInterface $mock, $arg, $add)
316 : {
317 26 : $container = $mock->mockery_getContainer();
318 26 : $names = explode('->', $arg);
319 26 : reset($names);
320 26 : if (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed()
321 26 : && !in_array(current($names), $mock->mockery_getMockableMethods())) {
322 0 : throw new \Mockery\Exception(
323 : 'Mockery\'s configuration currently forbids mocking the method '
324 0 : . current($names) . ' as it does not exist on the class or object '
325 0 : . 'being mocked'
326 0 : );
327 : }
328 26 : $exp = null;
329 26 : $nextExp = function ($n) use ($add) {return $add($n);};
330 26 : while (true) {
331 26 : $method = array_shift($names);
332 26 : $exp = $mock->mockery_getExpectationsFor($method);
333 26 : $needNew = false;
334 26 : if (is_null($exp) || empty($names)) {
335 26 : $needNew = true;
336 26 : }
337 26 : if ($needNew) $exp = $nextExp($method);
338 26 : if (empty($names)) break;
339 0 : if ($needNew) {
340 0 : $mock = $container->mock('demeter_' . $method);
341 0 : $exp->withNoArgs()->andReturn($mock);
342 0 : }
343 0 : $nextExp = function ($n) use ($mock) {return $mock->shouldReceive($n);};
344 0 : }
345 26 : return $exp;
346 : }
347 : }
|