1<?php
2/*
3 * This file is part of the PHPUnit_MockObject package.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11/**
12 * Implementation of the Builder pattern for Mock objects.
13 *
14 * @since File available since Release 1.0.0
15 */
16class PHPUnit_Framework_MockObject_MockBuilder
17{
18    /**
19     * @var PHPUnit_Framework_TestCase
20     */
21    private $testCase;
22
23    /**
24     * @var string
25     */
26    private $type;
27
28    /**
29     * @var array
30     */
31    private $methods = [];
32
33    /**
34     * @var array
35     */
36    private $methodsExcept = [];
37
38    /**
39     * @var string
40     */
41    private $mockClassName = '';
42
43    /**
44     * @var array
45     */
46    private $constructorArgs = [];
47
48    /**
49     * @var bool
50     */
51    private $originalConstructor = true;
52
53    /**
54     * @var bool
55     */
56    private $originalClone = true;
57
58    /**
59     * @var bool
60     */
61    private $autoload = true;
62
63    /**
64     * @var bool
65     */
66    private $cloneArguments = false;
67
68    /**
69     * @var bool
70     */
71    private $callOriginalMethods = false;
72
73    /**
74     * @var object
75     */
76    private $proxyTarget = null;
77
78    /**
79     * @var bool
80     */
81    private $allowMockingUnknownTypes = true;
82
83    /**
84     * @var PHPUnit_Framework_MockObject_Generator
85     */
86    private $generator;
87
88    /**
89     * @param PHPUnit_Framework_TestCase $testCase
90     * @param array|string               $type
91     */
92    public function __construct(PHPUnit_Framework_TestCase $testCase, $type)
93    {
94        $this->testCase  = $testCase;
95        $this->type      = $type;
96        $this->generator = new PHPUnit_Framework_MockObject_Generator;
97    }
98
99    /**
100     * Creates a mock object using a fluent interface.
101     *
102     * @return PHPUnit_Framework_MockObject_MockObject
103     */
104    public function getMock()
105    {
106        $object = $this->generator->getMock(
107            $this->type,
108            $this->methods,
109            $this->constructorArgs,
110            $this->mockClassName,
111            $this->originalConstructor,
112            $this->originalClone,
113            $this->autoload,
114            $this->cloneArguments,
115            $this->callOriginalMethods,
116            $this->proxyTarget,
117            $this->allowMockingUnknownTypes
118        );
119
120        $this->testCase->registerMockObject($object);
121
122        return $object;
123    }
124
125    /**
126     * Creates a mock object for an abstract class using a fluent interface.
127     *
128     * @return PHPUnit_Framework_MockObject_MockObject
129     */
130    public function getMockForAbstractClass()
131    {
132        $object = $this->generator->getMockForAbstractClass(
133            $this->type,
134            $this->constructorArgs,
135            $this->mockClassName,
136            $this->originalConstructor,
137            $this->originalClone,
138            $this->autoload,
139            $this->methods,
140            $this->cloneArguments
141        );
142
143        $this->testCase->registerMockObject($object);
144
145        return $object;
146    }
147
148    /**
149     * Creates a mock object for a trait using a fluent interface.
150     *
151     * @return PHPUnit_Framework_MockObject_MockObject
152     */
153    public function getMockForTrait()
154    {
155        $object = $this->generator->getMockForTrait(
156            $this->type,
157            $this->constructorArgs,
158            $this->mockClassName,
159            $this->originalConstructor,
160            $this->originalClone,
161            $this->autoload,
162            $this->methods,
163            $this->cloneArguments
164        );
165
166        $this->testCase->registerMockObject($object);
167
168        return $object;
169    }
170
171    /**
172     * Specifies the subset of methods to mock. Default is to mock all of them.
173     *
174     * @param array|null $methods
175     *
176     * @return PHPUnit_Framework_MockObject_MockBuilder
177     */
178    public function setMethods(array $methods = null)
179    {
180        $this->methods = $methods;
181
182        return $this;
183    }
184
185    /**
186     * Specifies the subset of methods to not mock. Default is to mock all of them.
187     *
188     * @param array $methods
189     *
190     * @return PHPUnit_Framework_MockObject_MockBuilder
191     */
192    public function setMethodsExcept(array $methods = [])
193    {
194        $this->methodsExcept = $methods;
195
196        $this->setMethods(
197            array_diff(
198                $this->generator->getClassMethods($this->type),
199                $this->methodsExcept
200            )
201        );
202
203        return $this;
204    }
205
206    /**
207     * Specifies the arguments for the constructor.
208     *
209     * @param array $args
210     *
211     * @return PHPUnit_Framework_MockObject_MockBuilder
212     */
213    public function setConstructorArgs(array $args)
214    {
215        $this->constructorArgs = $args;
216
217        return $this;
218    }
219
220    /**
221     * Specifies the name for the mock class.
222     *
223     * @param string $name
224     *
225     * @return PHPUnit_Framework_MockObject_MockBuilder
226     */
227    public function setMockClassName($name)
228    {
229        $this->mockClassName = $name;
230
231        return $this;
232    }
233
234    /**
235     * Disables the invocation of the original constructor.
236     *
237     * @return PHPUnit_Framework_MockObject_MockBuilder
238     */
239    public function disableOriginalConstructor()
240    {
241        $this->originalConstructor = false;
242
243        return $this;
244    }
245
246    /**
247     * Enables the invocation of the original constructor.
248     *
249     * @return PHPUnit_Framework_MockObject_MockBuilder
250     *
251     * @since  Method available since Release 1.2.0
252     */
253    public function enableOriginalConstructor()
254    {
255        $this->originalConstructor = true;
256
257        return $this;
258    }
259
260    /**
261     * Disables the invocation of the original clone constructor.
262     *
263     * @return PHPUnit_Framework_MockObject_MockBuilder
264     */
265    public function disableOriginalClone()
266    {
267        $this->originalClone = false;
268
269        return $this;
270    }
271
272    /**
273     * Enables the invocation of the original clone constructor.
274     *
275     * @return PHPUnit_Framework_MockObject_MockBuilder
276     *
277     * @since  Method available since Release 1.2.0
278     */
279    public function enableOriginalClone()
280    {
281        $this->originalClone = true;
282
283        return $this;
284    }
285
286    /**
287     * Disables the use of class autoloading while creating the mock object.
288     *
289     * @return PHPUnit_Framework_MockObject_MockBuilder
290     */
291    public function disableAutoload()
292    {
293        $this->autoload = false;
294
295        return $this;
296    }
297
298    /**
299     * Enables the use of class autoloading while creating the mock object.
300     *
301     * @return PHPUnit_Framework_MockObject_MockBuilder
302     *
303     * @since  Method available since Release 1.2.0
304     */
305    public function enableAutoload()
306    {
307        $this->autoload = true;
308
309        return $this;
310    }
311
312    /**
313     * Disables the cloning of arguments passed to mocked methods.
314     *
315     * @return PHPUnit_Framework_MockObject_MockBuilder
316     *
317     * @since  Method available since Release 1.2.0
318     */
319    public function disableArgumentCloning()
320    {
321        $this->cloneArguments = false;
322
323        return $this;
324    }
325
326    /**
327     * Enables the cloning of arguments passed to mocked methods.
328     *
329     * @return PHPUnit_Framework_MockObject_MockBuilder
330     *
331     * @since  Method available since Release 1.2.0
332     */
333    public function enableArgumentCloning()
334    {
335        $this->cloneArguments = true;
336
337        return $this;
338    }
339
340    /**
341     * Enables the invocation of the original methods.
342     *
343     * @return PHPUnit_Framework_MockObject_MockBuilder
344     *
345     * @since  Method available since Release 2.0.0
346     */
347    public function enableProxyingToOriginalMethods()
348    {
349        $this->callOriginalMethods = true;
350
351        return $this;
352    }
353
354    /**
355     * Disables the invocation of the original methods.
356     *
357     * @return PHPUnit_Framework_MockObject_MockBuilder
358     *
359     * @since  Method available since Release 2.0.0
360     */
361    public function disableProxyingToOriginalMethods()
362    {
363        $this->callOriginalMethods = false;
364        $this->proxyTarget         = null;
365
366        return $this;
367    }
368
369    /**
370     * Sets the proxy target.
371     *
372     * @param object $object
373     *
374     * @return PHPUnit_Framework_MockObject_MockBuilder
375     *
376     * @since  Method available since Release 2.0.0
377     */
378    public function setProxyTarget($object)
379    {
380        $this->proxyTarget = $object;
381
382        return $this;
383    }
384
385    /**
386     * @return PHPUnit_Framework_MockObject_MockBuilder
387     *
388     * @since  Method available since Release 3.2.0
389     */
390    public function allowMockingUnknownTypes()
391    {
392        $this->allowMockingUnknownTypes = true;
393
394        return $this;
395    }
396
397    /**
398     * @return PHPUnit_Framework_MockObject_MockBuilder
399     *
400     * @since  Method available since Release 3.2.0
401     */
402    public function disallowMockingUnknownTypes()
403    {
404        $this->allowMockingUnknownTypes = false;
405
406        return $this;
407    }
408}
409